Wi-Fi p2p

Connecting with Wi-Fi Direct
     Wi-Fi Direct™ APIs允许应用连接周围的设备,而不用通过网络或者热点,点对点直接连接。应用可以快速的发现周围设备并与之交互,而有效作用距离大于蓝牙。
     以下内容关于如何通过Wi-Fi Direct™发现和连接周围设备:
第一步:权限问题 Set Up Application Permissions
在manifest里添加三个权限:
CHANGE_WIFI_STATE,
ACCESS_WIFI_STATE,
INTERNET 。
Wi-Fi Direct™不需要网络,但是需要java socket,而java socket需要INTERNET 权限。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.nsdchat"
    ...
    <uses-permission
        android:required="true"
        android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission
        android:required="true"
        android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission
        android:required="true"
        android:name="android.permission.INTERNET"/>
    ...
第二步:新建广播接收器和点对点管理器
Set Up a Broadcast Receiver and Peer-to-Peer Manager
     使用Wi-Fi Direct™,需要监听(broadcast intents)广播intent,当有特定的事件发生时,你的应用就会觉察到。
在app里实例化一个IntentFilter对象出来,将其设置为监听以下内容:
WIFI_P2P_STATE_CHANGED_ACTION
Indicates whether Wi-Fi Peer-To-Peer (P2P) is enabled----P2P功能是否打开
WIFI_P2P_PEERS_CHANGED_ACTION
Indicates that the available peer list has changed.----可连接peer改变
WIFI_P2P_CONNECTION_CHANGED_ACTION
Indicates the state of Wi-Fi P2P connectivity has changed.----P2P连接状态改变
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
Indicates this device's configuration details have changed.----设备设置改变
private final IntentFilterintentFilter = new IntentFilter();
...
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //  Indicates a change in the Wi-Fi Peer-to-Peer status.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    // Indicates a change in the list of available peers.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    // Indicates the state of Wi-Fi P2P connectivity has changed.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    // Indicates this device's details have changed.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
    ...
}
     在onCreate()方法最后,取得一个WifiP2pManager实例,调用它的initialize()方法,这个方法返回一个WifiP2pManager.Channel对象,这个后面用来连接app和Wi-Fi Direct Framework。
@Override
Channel mChannel;
public void onCreate(Bundle savedInstanceState) {
    ....
    mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); //取得对象
    mChannel = mManager.initialize(this, getMainLooper(), null);   
}
     创建一个新的 BroadcastReceiver类,用来监听系统Wi-Fi P2P的变化状态,在 onReceive()方法里,增加condition条件来处理各种P2P状态的改变。 
 @Override
 public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();     //获取接收的intent里的action
        //以下进行判断,对各种不同的P2P状态改变,执行不同的代码
     if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
            // 检查 Wifi Direct模式是否开启
            int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
     if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
                activity.setIsWifiP2pEnabled(true);   //开启则...
            } else {
                activity.setIsWifiP2pEnabled(false);   //未开启则...
            }
        }
     else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
            // The peer list has changed!  We should probably do something about that.
          }
     else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
            // Connection state changed!  We should probably do something about that.
          }
      else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
            DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
                    .findFragmentById(R.id.frag_list);
            fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
                    WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
        }
    }
      最后,当你 主activity 激活以后,添加代码在onResume()方法里注册 intent filter 和 broadcast receiver 。当你的activity paused的时候,在onPause()方法里对它们解除注册。
    @Override
    public void onResume() {
        super.onResume();
        receiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
        registerReceiver(receiver, intentFilter);
    }
    @Override
    public void onPause() {
        super.onPause();      //调用父类方法
        unregisterReceiver(receiver);   //添加新的内容,解除注册
    } 
第三步:开始peer发现   Initiate Peer Discovery
调用discoverPeers()方法,来发现周围的设备。这个方法需要2个参数:
1. WifiP2pManager.Channel
2. WifiP2pManager.ActionListener 的一个新的实现
 第一个参数是一个对象,第二个参数是内部类对象
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            // Code for when the discovery initiation is successful goes here.
            // No services have actually been discovered yet, so this method
            // can often be left blank.  Code for peer discovery goes in the
            // onReceive method, detailed below.
        }
        @Override
        public void onFailure(int reasonCode) {
            // Code for when the discovery initiation fails goes here.
            // Alert the user that something went wrong.
        }
});
这只是启动peer discovery,方法discoverPeers()开始了发现线程,然后马上返回。如果peer discovery线程成功启动,系统就会注意到。发现一直持续直到建立连接或者建立一个P2P group。
 
第四步:获取peer 列表 Fetch the List of Peers
 首先实现WifiP2pManager.PeerListListener接口,这个接口提供了发现的peer的信息。
   private List peers = new ArrayList(); //装peer的list
    ...
    private PeerListListener peerListListener = new PeerListListener() {
        @Override
        public void onPeersAvailable(WifiP2pDeviceList peerList) {
            // Out with the old, in with the new.
            peers.clear();   //清空list,刷新
            peers.addAll(peerList.getDeviceList());
            // If an AdapterView is backed by this data, notify it
            // of the change.  For instance, if you have a ListView of available
            // peers, trigger an update.
            ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged();
            //如果peers.size()=0,则没有发现peer
            if (peers.size() == 0) {
                Log.d(WiFiDirectActivity.TAG, "No devices found");
                return;
            }
        }
    }
 
修改broadcast receiver的onReceive()方法,当接收到一个action包含WIFI_P2P_PEERS_CHANGED_ACTION的Intent的时候,调用requestPeers()方法,
需要把监听器传入接收器,方法之一就是把listener传入broadcast receiver构造器。 
 
public void onReceive(Context context, Intent intent) {
    ...
    else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
        // Request available peers from the wifi p2p manager. This is an
        // asynchronous call and the calling activity is notified with a
        // callback on PeerListListener.onPeersAvailable()
        if (mManager != null) {
            mManager.requestPeers(mChannel, peerListener);
        }
        Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
    }...

    这样的话,一个intent的action是 WIFI_P2P_PEERS_CHANGED_ACTION 的时候,就会触发更新peer list的请求。
 第五步:连接peer:Connect to a Peer
     要连接peer,就要new一个新的 WifiP2pConfig对象,并把想连接的peer的信息写入,最后调用 connect()方法。
  @Override
    public void connect() {
        // Picking the first device found on the network.
        WifiP2pDevice device = peers.get(0);
       WifiP2pConfig config = new WifiP2pConfig();
        config.deviceAddress = device.deviceAddress;
        config.wps.setup = WpsInfo.PBC;
        mManager.connect(mChannel, config, new ActionListener() {
            @Override
            public void onSuccess() {
                // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
            }
            @Override
            public void onFailure(int reason) {
                Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
     WifiP2pManager.ActionListener只是负责通知peer initiation是否成功,要监听P2P状态改变的话,就要实现WifiP2pManager.ConnectionInfoListener,它的onConnectionInfoAvailable()回调方法会在P2P状态改变时做出反应。在多个设备需要连接同一个设备的情况下,有一个设备会被指定为“group owner“。
   @Override
    public void onConnectionInfoAvailable(final WifiP2pInfo info) {
        // InetAddress from WifiP2pInfo struct.
        InetAddress groupOwnerAddress = info.groupOwnerAddress.getHostAddress());


        // After the group negotiation, we can determine the group owner.
        if (info.groupFormed && info.isGroupOwner) {
            // Do whatever tasks are specific to the group owner.
            // One common case is creating a server thread and accepting
            // incoming connections.
        } else if (info.groupFormed) {
            // The other device acts as the client. In this case,
            // you'll want to create a client thread that connects to the group
            // owner.
        }
    }
返回到 broadcast receiver里的 onReceive()方法,修改下, 接收到WIFI_P2P_CONNECTION_CHANGED_ACTION 这个intent的时候,调用requestConnectionInfo()方法。
..
        } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
      if (mManager == null) {
                return;
            }
   NetworkInfo networkInfo = (NetworkInfo) intent
                    .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
            if (networkInfo.isConnected()) {
                // We are connected with the other device, request connection
                // info to find group owner IP
                mManager.requestConnectionInfo(mChannel, connectionListener);
            }
            ...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Wi-Fi P2P技术规范v1.7是指Wi-Fi Direct技术的最新版本,它提供了一种在没有中间设备的情况下直接连接Wi-Fi设备的能力。以下是关于Wi-Fi P2P技术规范v1.7的一些主要内容。 1. 设备发现和连接:Wi-Fi P2P技术使用设备发现协议来使设备能够相互寻找和识别彼此。一旦设备被发现,它们可以通过Wi-Fi Direct通道进行连接,建立直接的无线连接。 2. 组形和管理:Wi-Fi P2P技术允许设备在没有传统的Wi-Fi网络基础设施的情况下组成点对点网络组。其中一个设备充当组主,其他设备则作为组成员。组主负责管理组中的连接,包括分配IP地址和管理连接状态。 3. 安全性:Wi-Fi P2P技术规范v1.7支持多种安全机制,包括WPA2-PSK、WPA2-Enterprise和WPS等。这些安全机制能够确保设备之间的通信是加密的,并防止未经授权的设备加入P2P网络。 4. 服务发现和应用:Wi-Fi P2P技术规范v1.7提供了一种服务发现机制,使设备能够在对等网络中查找和使用其他设备提供的服务。这为应用程序开发者提供了很大的灵活性,并可以通过Wi-Fi P2P来实现各种应用场景,如音频/视频流传输、共享文件和打印等。 总之,Wi-Fi P2P技术规范v1.7提供了一种易于使用且安全的无线直连技术,可以在没有中间设备的情况下实现设备之间的直接通信和互操作。它方便了用户之间的文件共享、设备连接和应用程序间的协作,为无线连接带来了更多便利和可能性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值