Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接

本文主要是介绍Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/wifi-direct.html#permissions

Wi-Fi peer-to-peer (P2P) APIs可以使程序与附近的设备进行直接通讯,Android的Wi-Fi P2P框架由Wi-Fi Direct™提供技术支持。WI-FI P2P技术可以使程序快速的检索附近的设备并与之建立连接。其覆盖范围超过蓝牙的覆盖范围。

这节课会学习如何通过WI-FI P2P技术搜索附近的设备并与之建立连接。

设置应用权限

如果要使用WI-FI P2P技术,需要在程序的清单文件中添加CHANGE\_WIFI\_STATE, ACCESS\_WIFI\_STATE, INTERNET三项权限。Wi-Fi P2P并不需要互联网连接,但是它需要使用标准的Java Socket通讯技术,所以需要使用INTERNET权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.android.nsdchat"...<uses-permissionandroid: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"/>...

设置广播接收器及P2P管理员

使用WI-FI P2P技术,需要监听广播意图,广播意图会通知程序某些事件的发生。所以在程序中需要添加IntentFilter,并设置其监听以下行为:

WIFI\_P2P\_STATE\_CHANGED\_ACTION

监听Wi-Fi P2P是否可用

WIFI\_P2P\_PEERS\_CHANGED\_ACTION

监听WI-FI P2P列表的变化

WIFI\_P2P\_CONNECTION\_CHANGED\_ACTION

监听Wi-Fi P2P的连接状态

WIFI\_P2P\_THIS\_DEVICE\_CHANGED\_ACTION

监听设备的配置变化
private final IntentFilter intentFilter = new IntentFilter();
...
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);//  Indicates a change in the Wi-Fi P2P 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的对象,它用于使程序应用层与Wi-Fi P2P框架建立连接。

@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()方法中,需要添加一些基本的判断条件来处理每种P2P的状态并处理:

    @Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {// Determine if Wifi P2P mode is enabled or not, alert// the Activity.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()方法与onPause()方法。

    /** register the BroadcastReceiver with the intent values to be matched */@Overridepublic void onResume() {super.onResume();receiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);registerReceiver(receiver, intentFilter);}@Overridepublic void onPause() {super.onPause();unregisterReceiver(receiver);}

初始化端点搜索

如果开始要使用Wi-Fi P2P来搜索附近的设备,需要调用discoverPeers()方法。这个方法要求传入以下参数:

  • 在初始化P2P管理员时获得的WifiP2pManager.Channel对象。
  • WifiP2pManager.ActionListener的实现,它用于监听搜索的成功与否。
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {@Overridepublic 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.}@Overridepublic void onFailure(int reasonCode) {// Code for when the discovery initiation fails goes here.// Alert the user that something went wrong.}
});

要记住,这里只是初始化了端点搜索。discoverPeers()方法启动搜索进程后会立即返回。如果端点搜索进程成功初始化,那么系统会自动调用初始化时设置的回调方法。另外,端点搜索功能会一直保持在活动状态,直到连接初始化完成或者P2P组建立连接。

获取端点列表

接下来需要获得并处理端点列表。首先需要实现WifiP2pManager.PeerListListener接口,它提供了WI-FI P2P所搜索到的端点信息。下面的代码演示了这个过程:

    private List peers = new ArrayList();...private PeerListListener peerListListener = new PeerListListener() {@Overridepublic void onPeersAvailable(WifiP2pDeviceList peerList) {// Out with the old, in with the new.peers.clear();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();if (peers.size() == 0) {Log.d(WiFiDirectActivity.TAG, "No devices found");return;}}}

现在需要修改广播接收器的onReceive()方法,在收到WIFI\_P2P\_STATE\_CHANGED\_ACTION行为时调用requestPeers()方法。在这之前需要将监听器的实例传入到广播接收器中,常规的方式是在广播接收器的构造方法中将这个监听器传进来。、

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, peerListListener);}Log.d(WiFiDirectActivity.TAG, "P2P peers changed");}...
}

现在,WIFI\_P2P\_STATE\_CHANGED\_ACTION的行为将会触发端点列表的更新。

连接到端点

为了可以连接到端点,需要创建一个新的WifiP2pConfig对象,然后将WifiP2pDevice中的数据拷贝进这个对象中。WifiP2pDevice代表的将要连接的设备。然后调用connect()方法。

    @Overridepublic 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() {@Overridepublic void onSuccess() {// WiFiDirectBroadcastReceiver will notify us. Ignore for now.}@Overridepublic void onFailure(int reason) {Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",Toast.LENGTH_SHORT).show();}});}

上述代码中的WifiP2pManager.ActionListener接口只有在初始化成功或者失败的情况下才会调用。如果要监听连接状态的变化,需要实现WifiP2pManager.ConnectionInfoListener接口,它的方法onConnectionInfoAvailable()会在连接状态发生变化的时候回调。在多台设备连接一台设备的情况下(比如多人互动的游戏或者聊天类的APP),其中一台设备会被指定为”group owner”。

    @Overridepublic 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.}}

现在回到广播接收器的onReceive()方法,修改监听WIFI\_P2P\_CONNECTION\_CHANGED\_ACTION的部分,当这个意图接收到时,调用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 IPmManager.requestConnectionInfo(mChannel, connectionListener);}...

这篇关于Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012984

相关文章

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

idea+spring boot创建项目的搭建全过程

《idea+springboot创建项目的搭建全过程》SpringBoot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目,:本文主要介绍idea+springb... 目录一.idea四种搭建方式1.Javaidea命名规范2JavaWebTomcat的安装一.明确tomcat

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二