WIFI P2P (WIFI直连)源码解析

原创 2015年11月20日 23:40:06

一:概述

直接看看效果

视频连接

wifi直连是可以不用在WiFi环境下利用wifi传输数据的方式(当然在wifi环境下也可以)。
下面是wifi联盟的解释:

这里写图片描述

并且这个wifi直连,并不是只是像蓝牙两台设备互联,可以3台及以上(没有测试过上限是多少台)。但是有个局限,就是必须其中一台设备担任groupowner角色。其他的设备担任peer角色。

 1.groupowner角色就像时一台服务器。其他是设备需要连接到此台设备上。
 2.peer角色就像是一个客户端。 并且可以有多个

类似下面这样(画的略丑):

这里写图片描述

我们现在大体讲讲连接过程:

现在我们假设有三台设备 A,B,C。

A主动和C连接了,C就成了Groupowner角色(第一次被动连接的一般是groupowner角色,但是我的三星note3列外,他怎么都时peer角色。),那么A就是peer角色。

以下假设都是A已经和C的连接的基础上。

 a.这时如果B主动去连C(Groupowner),那么直接连接成功。

 b.这时如果B主动连接A,连接不成功。

 c.这时如果A主动去连接B,这个时候B就是被邀请状态,会有一个弹窗提醒是否接受。
 (三星note3接受后还是连接失败。华为手机接受邀请后连接成功),这个弹窗是系统弹窗。

连接成功后就需要开始传输数据了:

1.A和C连接后A可以直接获取到C的ip地址(192.168.49.1)。

2.C就使用ServerSocket监听一个端口(e.g 8988)。

3.A使用socket主动连接groupowner(Ip+端口)。

4.传输数据

5.关闭serverSocket

接下来有个问题:

C如何主动给A传输数据呢?C不知道A设备的Ip呀。这下我们就需要使用上面的步骤主动的将A自己的ip传输给groupowner。然后C就可以使用ip+端口利用socket传输数据了。

好了现在又来了个问题:

A和C(groupowner)连接,B也和C连接。那A如何传数据给B呀。

只能通过C传输,A->C->B。(做好了数据协议,还是比较容易。这次写的源码没有实现这步)

二:源码解读

申明权限:

    //wifi p2p 是在Android 4.0以上使用
    <uses-sdk android:minSdkVersion="14" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

需要使用以下对象

     mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
     mChannel = mManager.initialize(this, getMainLooper(), null);

然后再注册一个广播:

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {

    } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {

    } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {

    } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {

    }

解释下:

WIFI_P2P_THIS_DEVICE_CHANGED_ACTION 这个分支中可以获取自己这台设备的信息。
WIFI_P2P_PEERS_CHANGED_ACTION 是查找设备(调用discoverPeers()),
   然后在这个分支中调用requestPeers()获取设备列表
WIFI_P2P_CONNECTION_CHANGED_ACTION wifi连接状态的改变。
WIFI_P2P_STATE_CHANGED_ACTION 就是wifi p2p可用还是不可用

我们先从查找设备开始:
查找成功后会发送一个广播。

mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                //会发送广播  WIFI_P2P_PEERS_CHANGED_ACTION
                Log.e("xhc", "搜索成功");
            }
            @Override
            public void onFailure(int reasonCode) {
                Log.e("xhc", "搜索失败-->" + reasonCode);
            }
  });

看看在广播中做了什么:
调用了mManager.requestPeers,其第二个参数是WifiP2pManager.PeerListListener
回调的方法是:onPeersAvailable()。嘿嘿,我们就可以得到我们查找到的设备了。

else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
                // Call WifiP2pManager.requestPeers() to get a list of current peers
      if (mManager != null) {
         //this 是指 WifiP2pManager.PeerListListener 
          mManager.requestPeers(mChannel, this);
      }
 }
...
 @Override
 public void onPeersAvailable(WifiP2pDeviceList peers) {
            stopLoading();
            listDevice.clear();
            listDevice.addAll(peers.getDeviceList());
            adapter.setList(listDevice);
  }

查找到了设备,我们就要开始连接啦。四不四很激动。
连接成功后也会发送一个广播。

  WifiP2pConfig config = new WifiP2pConfig();
  config.deviceAddress = wd.deviceAddress;
//  需要将address信息包装成WifiP2pConfig 
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {

            @Override
            public void onSuccess() {
                //广播:WIFI_P2P_CONNECTION_CHANGED_ACTION
            }

            @Override
            public void onFailure(int reason) {

            }
 });

再看看我们在这个广播中做了什么:

else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
                // Respond to new connection or disconnections
    NetworkInfo networkInfo = intent
                        .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
    if (networkInfo.isConnected()) {
         requestConnectionInfo(GoodActivity.this);
         // we are connected with the other device, request connection
         // info to find group owner IP
    }
}

...
//连接成功后,就去调用requestConnectionInfo(),请求信息。
 public void requestConnectionInfo(
            WifiP2pManager.ConnectionInfoListener listener) {
    mManager.requestConnectionInfo(mChannel, listener);
}
...

//回调的方法
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
//使用这个info就可以判断自己是不是groupowner角色
 if (!info.isGroupOwner) {
      //如果自己不是groupowner角色就将自己的ip传给groupowner端
      //详情看代码
      new ClientThread(...).start();
 }
}

忘了说。在程序已启动就开始监听自己的端口(不管是groupowner,还是peer端)。

   serverThread = new ServerThread(handler,this);
   serverThread.start();

peer只需要传数据给groupowner端,groupowner需要传数据给不同的peer端,所以需要一个HashMap key(devicename),value(deviceip)来保存不同peer的ip。

当然如果想两个peer端互传数据,peer端也需要保存不同peer的ip或者devicename也可以。

好了。差不多打完收工。

源码下载

加个好友共同学习(不是公众号):

这里写图片描述

因为小弟水平有限,如果有写的有问题,希望指出。

csdn写博客偶尔出现保存,发表失败。感觉内心有点小恐惧啊。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

wifi direct—深入理解Wi-Fi P2P

http://my.oschina.net/innost/blog/209795 《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第七章 深入理解Wi-Fi P2...
  • ztguang
  • ztguang
  • 2016年02月01日 00:00
  • 4808

《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第七章 深入理解Wi-Fi P2P

首先感谢各位兄弟姐妹们的耐心等待。根据今天得到的消息,本书预计在下周各大网店提供预订。注意,此处连载的是未经出版社编辑的原始稿件,所以样子会有些非专业。注意,如下是本章目录,本文节选7.1~7.2.2...
  • Innost
  • Innost
  • 2014年03月19日 21:13
  • 36830

WiFi P2P协议学习

基本功能与服务 P2P设备不能使用11b的速率传输数据和管理帧,除非 Probe Request帧要同时发送给P2P设备和非P2P设备 P2P设备不能响应显示只支持11b速率的Probe Reque...

WifiP2pService工作流程

android-5.1/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pService.java ...
  • zhqh100
  • zhqh100
  • 2015年04月07日 17:27
  • 2108

WIFI DIRECT开发(三)P2P传输技术-WIFI Direct

部分引用他人的博客。表示感谢 一.产品的体系结构 WiFi模块主要包括三部分:WLAN Station,WiFi Direct, Mobileap(Hotspot)(热点) ,应用主要涉及上网、打...

WifiP2pService的启动以及P2P的连接

这一章主要总结从WifiP2pService的启动到用户通过四种连接方式连接P2P的过程,四种方式包括:主动连接、被动连接、主动invite和被动invite。首先来看WifiP2pService的启...
  • sadamoo
  • sadamoo
  • 2014年08月16日 11:16
  • 3791

WIFI Direct/WIFI P2P

上节说过了网卡的选型,之所以网卡的选型如此重要,主要是因为Miracast网卡相比较于普通的网卡多了个P2P功能,底层可靠了,才能很好的进行接下来的上层开发,如果我们已经有了可靠的P2P网卡以及网卡驱...

Android Wifi Direct 安卓手机间wifi直连

 Wi-Fi Direct™的API允许应用程序不通过网络或热点,直接与周围的设备进行连接。应用程序可以迅速地查找附近的设备,交换信息。并且与蓝牙相比,Wi-Fi Direct的通讯范围更大。 ...
  • hack8
  • hack8
  • 2014年04月13日 23:19
  • 29576

Android -wifi 直连(wifi direct )

现在,Android的支持Wi -Fi的直接点对点点对点(P2P)Android系统的供电设备和其他类型的设备,没有一个热点或互联网连接之间的连接。Android框架提供了一套Wi - Fi的P2P的...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WIFI P2P (WIFI直连)源码解析
举报原因:
原因补充:

(最多只允许输入30个字)