Android中的WiFi P2P

Android中的WiFi P2P能够允许一定范围内的设备通过Wifi直接互连而不必通过热点或互联网。

使用WiFi P2P需要Android API Level >= 14才可以,而且不要忘记在Manifest文件中加入下面5个权限:

● android.permission.ACCESS_WIFI_STATE

● android.permission.CHANGE_WIFI_STATE

● android.permission.ACCESS_NETWORK_STATE

● android.permission.CHANGE_NETWORK_STATE

● android.permission.INTERNET  (WiFi P2P并不需要连接互联网,但是因为要用到Java Socket,所以要加这个权限)

关于WiFi P2P的操作几乎都靠WifiP2pManager来进行,所以如果你的程序要用到WiFi P2P功能,可以设置一个全局变量wifiP2pManager,然后在onCreate()生命函数中获取系统WifiP2pManager对象:

<span style="font-family:Microsoft YaHei;">wifiP2pManager = (WifiP2pManager) getApplicationContext().getSystemService(Context.WIFI_P2P_SERVICE);</span>

WifiP2pManager有如下方法可以很方便的进行P2P操作:

方法 功能
initialize() 在使用WiFi P2P功能时必须先调用这个方法,用来通过WiFi P2P框架注册我们的应用
connect() 根据配置(WifiP2pConfig对象)与指定设备(WifiP2pDevice对象)进行P2P连接
cancelConnect() 关闭某个P2P连接
requestConnectInfo() 获取设备的连接信息
createGroup() 以当前的设备为组长创建P2P小组
removeGroup() 移除当前的P2P小组
requestGroupInfo() 获取P2P小组的信息
discoverPeers() 初始化peers发现操作
requestPeers() 获取当前的peers列表(通过discoverPeers发现来的)

每当WifiP2pManager执行某个P2P操作时,可以通过不同的监听器来检测这些操作的反馈结果,这些监听器的类型如下:

监听器 关联的行为
WifiP2pManager.ActionListener connect()cancelConnect()createGroup()removeGroup()discoverPeers()
WifiP2pManager.ChannelListener initialize()
WifiP2pManager.ConnectionInfoListener requestConnectInfo()
WifiP2pManager.GroupInfoListener requestGroupInfo()
WifiP2pManager.PeerListListener requestPeers()

那么接下来就可以讲解如何使用WiFi P2P了。

一. 准备工作

准备阶段需要让我们的应用可以接受P2P信号,这就需要一个意图广播接收器,要创建一个符合我们要求的广播接收器需要准备下面3个要素:

(1) 一个意图广播接收器,用来接受意图广播。

(2) 通过WifiP2pManager的initialize()初始化操作来获取一个Channel对象,用于以后和WiFi P2P框架保持通信。

(3) 自己包装BroadcastReceiver类,实现一个接收器。

意图过滤器使用如下方法创建:

// 设置intent过滤器
intentFilter = new IntentFilter();  //一个全局的intentFilter对象
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);       // WiFi P2P是否可用
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);       // peers列表发生变化
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);  // WiFi P2P连接发生变化
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); // WiFi P2P设备信息发生变化(比如更改了设备名)

Channel的获取方法:

channel = wifiP2pManager.initialize(getApplicationContext(), getMainLooper(), null); // channel是一个全局的Channel对象

意图广播接收器的创建需要通过继承BroadcastReceiver类来自己实现,下面给出了一段示例:

class MyBroadcastReceiver extends BroadcastReceiver {
	// 使用WiFi P2P时,自己定义的BroadcastReceiver的构造函数一定要包含下面这三个要素
	private WifiP2pManager wifiP2pManager;
	private Channel channel;
	private Activity activity;

	public MyBroadcastReceiver(WifiP2pManager wifiP2pManager, Channel channel, Activity activity) {
		this.wifiP2pManager = wifiP2pManager;
		this.channel = channel;
		this.activity = activity;
	}

	// onReceiver对相应的intent进行处理
	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
			int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
			if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
				// WiFi P2P 可以使用
			} else {
				// WiFi P2P 不可以使用
			}
		} 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)) {
		}
	}
}

定义完了之后就可以再需要的地方实例化一个意图广播接收器对象了:

broadcastReceiver = new MyBroadcastReceiver(wifiP2pManager, channel, this);

那么三个要素都具备了之后就要向应用注册我们的接收器,好让它可以开始工作:

registerReceiver(broadcastReceiver, intentFilter);

二. 启动peers发现

public void discoverPeers(View view) {
	peerListListener = new WifiP2pManager.PeerListListener() {
		@Override
		public void onPeersAvailable(WifiP2pDeviceList peerList) {
			peers.clear();   // peers是一个全局ArrayList对象,用于保存发现的peers的信息
			peers.addAll(peerList.getDeviceList());
			// 如果你有一个控件用来显示这些peers的信息,就可以再这里更新了
		}
	};

	wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
		@Override
		public void onSuccess() {
			Toast.makeText(getApplicationContext(), "discover peers!", Toast.LENGTH_SHORT);
		}

		@Override
		public void onFailure(int arg0) {
		}
	});
	// discoverPeers是异步执行的,调用了之后会立刻返回,但是发现的过程一直在进行,
	// 直到发现了某个设备时就会通知你
}

当发现了设备之后就会触发WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION意图广播,你可以再之前自己包装的BroadcastReceiver类中加入对这一意图的处理:

else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
	if (wifiP2pManager != null) {
		wifiP2pManager.requestPeers(channel, peerListListener);
	}
}

三. 与peers建立连接

public void connect() {
	final WifiP2pDevice device = (WifiP2pDevice) peers.get(0); //从peers列表中获取发现来的第一个设备
	WifiP2pConfig config = new WifiP2pConfig();
	config.deviceAddress = device.deviceAddress;
	config.wps.setup = WpsInfo.PBC;

	wifiP2pManager.connect(channel, config, new WifiP2pManager.ActionListener() {
		@Override
		public void onSuccess() {
			// 连接成功
			Toast.makeText(getApplicationContext(), "与设备" + device.deviceName + "连接成功", Toast.LENGTH_LONG).show();
		}

		@Override
		public void onFailure(int arg0) {
			// 连接失败
			Toast.makeText(getApplicationContext(), "与设备" + device.deviceName + "连接失败", Toast.LENGTH_LONG).show();
		}
	});
}

每当有P2P连接状态发生改变时,就会触发WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION意图广播,可以在之前你自己包装的BroadcastReceiver类中加入对这一意图的处理:

else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
	if (wifiP2pManager == null)
		return;

	NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
<span style="white-space:pre">	</span>if (networkInfo.isConnected()) {

		// We are connected with the other device, request
		// connection
		// info to find group owner IP

		wifiP2pManager.requestConnectionInfo(channel, new WifiP2pManager.ConnectionInfoListener() {
			@Override
			public void onConnectionInfoAvailable(WifiP2pInfo info) {
				// 这里可以查看变化后的网络信息

				// 通过传递进来的WifiP2pInfo参数获取变化后的地址信息
				InetAddress groupOwnerAddress = info.groupOwnerAddress;
				// 通过协商,决定一个小组的组长
				if (info.groupFormed && info.isGroupOwner) {
					// 这里执行P2P小组组长的任务。
					// 通常是创建一个服务线程来监听客户端的请求
				} else if (info.groupFormed) {
					// 这里执行普通组员的任务
					// 通常是创建一个客户端向组长的服务器发送请求
				}
			}
		});
	}
}

如果转载请注明出处:http://blog.csdn.net/gophers

时间: 2024-10-12 02:59:34

Android中的WiFi P2P的相关文章

android 中判断WiFi是否可用的可靠方法 ,android 是否联网

http://alex-yang-xiansoftware-com.iteye.com/blog/619841 在一些程序中,需要从网上下载数据,或者通过其他方式对网络产生流量,当wifi不可用时应该提示用户wifi已经不可用了,是否继续,因为如果wifi掉了,那么程序可能采用3G卡或其他的收费的渠道使用网络,会导在不知情时产生大量的上网费用.通过查看android的api可使用下列方法进行判断: public static boolean isWiFiActive(Context inCont

Android连接指定Wifi的方法

本篇博客主要记录一下Android中打开Wifi.获取Wifi接入点信息及连接指接入点的方法. 自己写的demo主要用于测试接口的基本功能,因此界面及底层逻辑比较粗糙. demo的整体界面如下所示: 上图中的OPEN按键负责开启Wifi: GET按键负责获取扫描到的接入点信息. 当获取到接入点信息后,我选取了其中的名称及信号强度,以列表的形式显示在主界面下方,如下图: 当点击列表中的Item时,就会去连接对应的接入点. 自己的逻辑比较简单,测试时的代码,假定连接的是不许要密码或密码已知的接入点.

Android Wi-Fi Peer-to-Peer(Android的Wi-Fi P2P对等网络)

Wi-Fi peer-to-peer(P2P,对等网络),它同意具备对应硬件的Android 4.0(API level 14)或者更高版本号的设备能够直接通过wifi而不须要其他中间中转节点就能直接通信(Android的Wi-Fi P2P框架符合Wi-Fi联盟的Wi-Fi Direct?直连认证标志).使用这些API.你能够搜索并连接其他相同支持Wi-Fi P2P的设备,然后再通过一个快速的连接进行互相通信,而且这个连接的有效距离要比蓝牙连接的有效距离要长的多. 这对于须要在用户之间共享数据的

转自邓凡平 《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第七章 深入理解Wi-Fi P2P部分节选

本章主要内容: 介绍Wi-Fi P2P相关知识: 介绍Android中WifiP2pService.wpa_supplicant的相关代码. 7.1  概述 承接第6章介绍的WSC,本章将继续介绍Wi-Fi Alliance(Wi-Fi联盟)推出的另外一项重要技术规范Wi-Fi P2P.该规范的商品名为Wi-Fi Direct,它支持多个Wi-Fi设备在没有AP的情况下相互连接. 在Android平台的Wi-Fi相关模块中,P2P的功能点主要集中在: Android Framework中的Wif

【Android】 Android-wifi 直连 wifi direct wifi p2p

现在,Android的支持Wi -Fi的直接点对点点对点(P2P)Android系统的供电设备和其他类型的设备,没有一个热点或互联网连接之间的连接.Android框架提供了一套Wi - Fi的P2P的API,允许你去发现和连接到其他设备时,每个设备的Wi -Fi的直接支持,然后沟通跨越距离远远长于蓝牙连接迅速??连接. android.net.wifi.p2p,一个新的软件包,包含所有的API执行同行等连接与Wi - Fi. 你需要与主类是WifiP2pManager,您可以调用getSyste

转-Android中自动连接到指定SSID的Wi-Fi

最近在做一个项目,其中涉及到一块"自动连接已存在的wifi热点"的功能,在网上查阅了大量资料,五花八门,但其中一些说的很简单,即不能实现傻瓜式的拿来就用,有些说的很详细,但其中不乏些许错误造成功能无法实现,经过浣熊多方努力,终于成功将功能实现,遂将一点点小成就拿出来与大家分享. 在这篇文章中,作者定义了一个wifi工具类,其中存在着操作wifi的各种方法,其中有一些错误我以改正,正确的代码如下(创建一个名为WifiAdmin.java的文件,以下代码中没有包声明和import,请自行添

Android中可以做的两件坏事---破解锁屏密码和获取Wifi密码

之前的文章一直在介绍OC,最近也是在找急忙慌的学习IOS,所以Android方面的知识分享就有点中断了,但是我现在还是要靠Android吃饭,所以不能Android的工作不能停呀,今天咋们来看一下我在现实中遇到的两个问题和解决方案 问题一:忘记手机的锁屏密码了 Android中在设置中的安全菜单栏中是可以设置锁屏密码的,有直接的文本密码和手势密码(我们一般会用到的两个密码),但是有时候脑子不好使,密码总是忘了,到时候该怎么办呢? 方法一:我们知道现在最流行的手势锁就是九宫格了,他在设置手势的时候

Android中可以做的两件坏事——破解锁屏密码和获取Wifi密码

今天咋们来看一下我在现实中遇到的两个问题和解决方案 问题一:忘记手机的锁屏密码了 Android中在设置中的安全菜单栏中是可以设置锁屏密码的,有直接的文本密码和手势密码(我们一般会用到的两个密码),但是有时候脑子不好使,密码总是忘了,到时候该怎么办呢? 方法一:我们知道现在最流行的手势锁就是九宫格了,他在设置手势的时候,是有一定规则的,比如手势点不能少于4个,而且有些手势是不存在的,一般手势是九宫格,每个点代表一个数值: 0     1     2 3     4     5 6     7  

Android 4.2 Wifi Display 之 Settings 源码分析(一)

一.简单背景 简单背景:随着无线互联的深入,不管是蓝牙.WIFI或者各种基于此的规范不管是UPNP还是DLNA都随着用户的需求得到了很大的发展,google 自从android 4.0引入wifi direct后,又在11月份公布的android 4.2中引入了Miracast无线显示共享,其协议在此可以下载.具体的协议部分内容比较多,本人由于水平有限,就不在这里罗列协议的内容了,只附上一份架构图供大家对其有个大致的印象. 英文缩写对应如下: HIDC: Human Interface Devi