(Android)Wifi-Direct直连

因项目需要Pad端和手机端交互,采用wifi直连。查阅资料,大概写下一些资料和收获吧。注:大公司的代码带不出来,我也比较懒不想再认真去写一遍了,所以大概这个意思哦。

wifi直连也叫做wifi设备点对点连接(peer-peer),不需要连接热点或者网络,需要打开wifi,就可以查找到附近的设备。大概可以分为以下步骤:1.设置以下权限,并且注意最小sdk=14

2.创建一个广播接收器,通过创建IntentFilter来addAction得到各个特定事件的发生来进行回调.

创建一个新的 BroadcastReceiver 类,用来监听系统的Wi-Fi P2P状态的改变(在 onReceive方法中,添加一个条件来处理上面列出的各种P2P状态的变更。)

 

最后,在主活动激活时,注册意图过滤器(Intent Filter)和广播接收器;在主活动暂停时把它们注销。最好在onResume()和onPause()方法中完成该操作。

3.初始化得到WifiP2pManager和Channel实例,在onCreate()方法中初始化,如果是在Fragment中,initialize参数用Looper.getMainLooper(),

4.初始化搜索,只初始化了对等点的搜索。discoverPeers()方法启动了搜索线程,并立刻返回。系统通过调用给定的动作监听器的方法来进行初始化,并会在成功初始化对等点进程时通知你。同时,搜索也会持续进行,直到一个连接被初始化,或者一个P2P组形成。

5.获取搜索到设备列表, 获取对等点的列表并进行处理,首先实现 WifiP2pManager.PeerListListener 接口,它提供了Wi-Fi Direct检测到的对等点信息。注:在公司当时我是在这个方法里实现自动连接,保存到sharedPreference,然后如果有搜索到相同的设备名和地址,代码就不写出来了,有更好的想法的可以说下。

 

在广播onReceive()方法中以便在收到一个带有 WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION 动作的意图(Intent)时调用 requestPeers方法。把实现PeerListListener的类作为方法参数传进去进行监听器回调。

6.连接(后面具体说)这个是重点哦

为了连接一个对等点,需要先创建一个新的 WifiP2pConfig 对象,然后从代表你想连接的设备的 WifiP2pDevice 中拷贝数据进去。再调用 connect 方法。然后项目需求是Pad端一定要作为group owner,这时候config.groupOwnerIntent = 15,增加这句话并不能一定作为group owner,只是一个建议。

 

         WifiP2pConfig config = new WifiP2pConfig();
                        config.deviceAddress = device.deviceAddress;
                        config.wps.setup = WpsInfo.PBC;

 为了兼容传统的Wifi设备,Wifi_Direct其实还存在另一种使用方 式,暂且称为兼容模式。兼容模式的特点在于,只需要担任GroupOwner的设备支持Wifi_Direct,而其他设备只需要支持传统的Wifi就可以了(个人觉得其实这种使用模式很像Android的便携热点功能)。

         操作流程为:
         1. 支持Wifi_Direct的设备创建group,WifiP2pManager.createGroup(),成为GroupOwner
         2.  其他设备扫描Wifi_Direct设备创建group后产生的Wifi热点并连接即可。
  
         兼容模式存在的一个问题是:因为作为group member的设备是使用Wifi硬件接入到group中,所以会导致member进行wifi 热点切换以及网络中断,可能对正在进行的网络操作造成影响,而group owner则不存在这个问题。另外,而WifiP2p配对的使用方式,WifiP2p和Wifi可以独立运作,相互不受影响。
          但是,兼容模式因为省去了扫描和配对的过程,所以建立连接的成功率明显提升,并且建立连接的速度要快不少(具体时间比较随机)。
          从个人的使用感觉来讲,这WifiP2p这套API接口高度的异步化,API都需要以回调的方式获取操作结果(包内interface比较多的原因就在于 此)。更加麻烦的是,几个关键API(例如WifiP2pManager.connect)的回调获取到的结果仅仅是执行是否开始,真正的结果还得注册 broadcast receiver,通过监听广播来获得,才能进行下一步操作。异步的设计提高了代码的逻辑复杂度。

 

7.连接信息获取要监听连接状态的变更,需要实现 WifiP2pManager.ConnectionInfoListener 接口,回调函数 onConnectionInfoAvailable将会在连接状态改变时通知。

 

回到广播接收器的onReceive方法中,修改监听WIFI_P2P_CONNECTION_CHANGED_ACTION的部分。收到该意图(Intent)时,调用 requestConnectionInfo。这是一个异步的调用,所以结果会传给作为参数的连接信息监听器。

8.断连

removeGroup是移除群组,断连所有设备。

 

cancelConnect是取消连接状态为Invited的设备

一些问题:

如何获得WifiP2pGroupInfo,它有什么用?

WifiP2pManager.requestGroupInfo()函数,可以获取GroupInfo,较为有用的api有:
1. GroupInfo.getClientList()可以获得连接到group的member列表
2. GroupInfo.getNetWorkName()可以获得group的wifi热点名称(SSID)
3. GroupInfo.getPassphrase() 可以获得连接到wifi 热点的密码
 
如何防止配对产生的提示框?
在不修改framework的情况下,本人暂时为找到可行的方案。
这个提示狂是由系统提供的,具体表现视设备而定。nexus只在第一次配对的时候弹出,而A80每一次配对都会弹出。
但是,使用兼容模式使用Wifi_Direct是没有提示框的。
 
7. WifiP2pManager.discovePeers 仅仅返回附近有哪些设备开启了wifi p2p,而app的实际使用场景,往往希望寻找可以提供某些特定服务的设备。例如同一房间内,有A,B,C,D四台设备开启了wifi p2p,而A设备和B设备都安装了app1,C设备和D设备都安装了app2,使用者希望A设备能和B设备配对连接,而C设备与D设备连接,运行在A设备 上的app1如何识别它应该连接的是B设备,而非C、D设备呢?

为了支持更加个性化的设备发现,WifiP2pManager支持UPNP和DNS两种方式的设备(服务?)发现。
App可以通过WifiP2pManager.addLocalService来向周边的设备广播自己支持哪些服务。
也可以通过如下步骤实现发现这些服务:
1. 通过WifiP2pManager.addServiceRequest()添加服务请求
2. 通过WifiP2pManager.discoverService()开始服务发现
3. 通过WifiP2pManager.setDnsSdResponseListener()或者WifiP2pManager.setUpnpServiceResponseListener()监听服务内容。

转载于:https://www.cnblogs.com/lyfshare/p/5805225.html

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,作为AI语言模型,我没有能力编写代码。但是,我可以为您提供一些基本的思路和参考资料: 1. 首先需要在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> ``` 2. 创建一个WifiP2pManager对象,并注册用于接收wifi-direct连接状态的广播接收器。 ``` WifiP2pManager mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); WifiP2pManager.Channel mChannel = mManager.initialize(this, getMainLooper(), null); BroadcastReceiver mReceiver = new WifiDirectBroadcastReceiver(mManager, mChannel, this); IntentFilter mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); registerReceiver(mReceiver, mIntentFilter); ``` 3. 发现可用的wifi-direct设备,并选择要连接的设备。 ``` mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Toast.makeText(MainActivity.this, "发现设备成功!", Toast.LENGTH_SHORT).show(); } @Override public void onFailure(int reasonCode) { Toast.makeText(MainActivity.this, "发现设备失败!", Toast.LENGTH_SHORT).show(); } }); mManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() { @Override public void onPeersAvailable(WifiP2pDeviceList peerList) { // 列出可用的设备列表 } }); WifiP2pDevice device = peerList.getDeviceList().get(0); WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Toast.makeText(MainActivity.this, "连接成功!", Toast.LENGTH_SHORT).show(); } @Override public void onFailure(int reason) { Toast.makeText(MainActivity.this, "连接失败!", Toast.LENGTH_SHORT).show(); } }); ``` 4. 在连接建立后,可以使用Socket进行通信。 ``` ServerSocket serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(port)); Socket clientSocket = serverSocket.accept(); Socket socket = new Socket(); socket.connect(new InetSocketAddress(ip, port)); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); byte[] buffer = new byte[1024]; int len = inputStream.read(buffer); String message = new String(buffer, 0, len); outputStream.write("Hello, World!".getBytes()); ``` 以上是一个简单的wifi-direct连接的流程,具体实现还需要根据具体业务需求进行调整。同时,还可以参考以下官方文档: - [Wi-Fi P2P developer guide](https://developer.android.com/guide/topics/connectivity/wifip2p) - [Android Wi-Fi Direct Example](https://www.journaldev.com/10860/android-wifi-direct-example) - [WifiP2pManager](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值