android学习(十九) 使用无线连接设备(二) 用Wi-Fi P2P创建连接
来源:互联网 发布:网络主播当红10首歌曲 编辑:程序博客网 时间:2024/06/08 12:03
WIFI-P2P允许你的应用快速查找和交互附近的设备,这是一个在蓝牙范围外的功能。
WIFI-P2P API允许应用在无需连接网络或热点的情况下连接附近设备。如果你的应用被设计成一个安全的近距离的网络,WIFI是一个更合适的选择。
设置应用的权限
<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"/>
设置广播接收器和P2P管理
为了使用WIFI-P2P,你需要监听广播Intent,告诉你的应用某些事情已经发生。实例化IntentFilter并且设置如下监听:
WIFI_P2P_STATE_CHANGED_ACTION:表示WIFI-P2P是否启动。
WIFI_P2P_PEERS_CHANGED_ACTION:表示可用的端口列表已经改变。
WIFI_P2P_CONNECTION_CHANGED_ACTION:表示Wi-Fi P2P连接状态已发生变化。
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:表示此设备的配置详细信息已更改。
private final IntentFilter intentFilter = new IntentFilter(); @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); }
获取WifiP2pManager并且调用initialize()方法,返回一个WifiP2pManager.Channel类。
... private WifiP2pManager.Channel mChannel; private WifiP2pManager mManager; @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... mManager = (WifiP2pManager) this.getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(this,getMainLooper(),null); }
接下来创建一个BroadcastReceiver类,它用于监听系统的Wi-Fi P2P的状态变化,在onReceive()方法中,需要添加一些基本的判断条件来处理每种P2P的状态并处理:
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { private MainActivity activity; private WifiP2pManager mManager; private Channel mChannel; public WiFiDirectBroadcastReceiver(WifiP2pManager mManager, Channel mChannel, MainActivity activity) { this.activity = activity; this.mManager = mManager; this.mChannel = mChannel; } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){ //确认WIFI-P2P是否启动 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)){ //对等列表已更改!我们应该做点什么 } else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){ //连接状态改变 } else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){ //此设备的配置详细信息已更改 Toast.makeText(context.getApplicationContext(),action,Toast.LENGTH_SHORT).show(); } }}
最后,将广播接收器与意图过滤器添加到上下文中,并需要在Activity暂停的时候注销这个广播接收器。放置这些代码的最佳位置就是onResume()方法与onPause()方法。
@Override protected void onResume() { super.onResume(); receiver = new WiFiDirectBroadcastReceiver(mManager,mChannel,this); registerReceiver(receiver,intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); } public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled){ if(isWifiP2pEnabled){ Toast.makeText(this,"WifiP2p连接成功",Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this,"WifiP2p连接失败",Toast.LENGTH_SHORT).show(); } }
初始化端口搜索
调用WifiP2pManager.discoverPeers()他继承WifiP2pManager.ActionListener接口用于监听搜索成功与否
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { } @Override public void onFailure(int reason) { //提醒用户出错了 } });
要记住,这里只是初始化了端点搜索。discoverPeers()方法启动搜索进程后会立即返回。如果端点搜索进程成功初始化,那么系统会自动调用初始化时设置的回调方法。另外,端点搜索功能会一直保持在活动状态,直到连接初始化完成或者P2P组建立连接。
获取对等设备列表
现在获取对等列表,首先需要继承* WifiP2pManager.PeerListListener*接口,它提供了WI-FI P2P所搜索到的端点信息。添加代码到BroadcastReceiver类。
private List<WifiP2pDevice> peers = new ArrayList<>(); private WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() { @Override public void onPeersAvailable(WifiP2pDeviceList peerList) { List<WifiP2pDevice> refreshedPeers = (List<WifiP2pDevice>) peerList.getDeviceList(); if(!refreshedPeers.equals(peers)){ peers.clear(); peers.addAll(refreshedPeers); //可以通过一个ListView显示 //需要多个人连接才能获取他人信息 } if(peers.size() == 0){ Log.d(WiFiDirectActivity.TAG, "No devices found"); return; } } };
现在需要重新设置WIFI_P2P_PEERS_CHANGED_ACTION的验证。
public void onReceive(Context context, Intent intent) { ... else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { if (mManager != null) { mManager.requestPeers(mChannel, peerListListener); } Log.d(WiFiDirectActivity.TAG, "P2P peers changed"); }...}
连接一个对等设备
为了连接一个端口,需要创建一个新的WifiP2pConfig对象,并且从WifiP2pDevice拷贝数据。代表你想连接这个设备。WifiP2pManager调用connect()方法。
WifiP2pDevice device = peers.get(position); WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; config.wps.setup = WpsInfo.PBC; mManager.connect(mChannel, config, new ActionListener() { @Override public void onSuccess() { } @Override public void onFailure(int reason) { Toast.makeText(WiFiDirectActivity.this, "连接失败", Toast.LENGTH_SHORT).show(); } });
如果在你的组里面每一个设备都支持wifi直连,当你连接时,你不需要明确的告诉这个组密码。为了允许不支持WIFI直连的设备加入群,你需要调用requestGroupInfo()来检索密码。
mManager.requestGroupInfo(mChannel, new WifiP2pManager.GroupInfoListener() { @Override public void onGroupInfoAvailable(WifiP2pGroup group) { if(group!=null){ String groupPassword = group.getPassphrase(); } } });
上述代码中的WifiP2pManager.ActionListener接口只有在初始化成功或者失败的情况下才会调用。如果要监听连接状态的变化,需要实现WifiP2pManager.ConnectionInfoListener接口,它的方法onConnectionInfoAvailable()会在连接状态发生变化的时候回调。在多台设备连接一台设备的情况下(比如多人互动的游戏或者聊天类的APP),其中一台设备会被指定为”群组的拥有者”。
else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){ Log.d("connection",action); //连接状态改变 if(mManager==null){ Log.d("connection","null"); return; } NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if(networkInfo.isConnected()){ mManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() { @Override public void onConnectionInfoAvailable(WifiP2pInfo info) { //获取拥有者的地址。 String groupOwnerAddress = info.groupOwnerAddress.getHostAddress(); Log.d("connection",groupOwnerAddress); if(info.groupFormed&&info.isGroupOwner){ //做任何只属于管理者的的任务。一个常见的情况是创建一个组所有者线程和接受权限 }else if(info.groupFormed){ //其他设备是对等,在这种情况下需要管理者创建对等线程。 } } }); } }
创建一个组
如果你想让设备作为一个网络运用你的应用包括传统设备,设备不支持WIFI Direct–你应该以相同的顺序步骤在连接对等部分。除非你创建一个新的WifiP2pManager.ActionListener()使用createGroup()替代connect()。
mManager.createGroup(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { //设备准备接受来自同等级的传入连接。 } @Override public void onFailure(int reason) { Toast.makeText(WiFiDirectActivity.this, "P2P 组创建失败", Toast.LENGTH_SHORT).show(); }});
注:如果在一个网络支持Wi-Fi Direct的所有设备,你可以使用connect()方法在每个设备因为方法然后创建组和拥有者自动选择一组。
你创建一个组后,你可以调用requestgroupinfo()检索网络上的节点的详细信息,包括设备名称和连接状态。
摘自android developer
- android学习(十九) 使用无线连接设备(二) 用Wi-Fi P2P创建连接
- android学习(十九) 使用无线连接设备(三) 通过P2P搜索网络服务
- Android - 创建Wi-Fi热点、连接Wi-Fi
- android学习(十九) 使用无线连接设备(一) 使用网络发现服务(NSD)
- Wi-Fi p2p
- 链接:Wi-Fi P2P
- Wi-Fi Direct(Wi-Fi P2P)
- Android---用Wi-Fi来建立对等连接
- Android---用Wi-Fi来建立对等连接
- Android Wi-Fi Peer-to-Peer(Android的Wi-Fi P2P对等网络)
- PPC与PC无线连接(Wi-Fi)
- PPC与PC无线连接(Wi-Fi)
- Android Wi-Fi AP侧查看已连接的Android设备名
- Android Wi-Fi 连接/断开时间
- Android---把Wi-Fi P2P用于服务发现
- wpa_supplicant and Wi-Fi P2P
- 深入理解Wi-Fi P2P
- Android Wi-Fi子系统学习笔记
- Gradle项目构建工具介绍
- jsonp的奥秘
- LeetCode (Longest Common Prefix)
- Python的生成器
- SylixOS文件记录锁使用
- android学习(十九) 使用无线连接设备(二) 用Wi-Fi P2P创建连接
- VMware安装centos7.0如何连接网络
- 属性动画
- CNN实现的几种方法
- 【OpenCV3】级联分类器训练——traincascade快速使用详解
- 一个字母的代价
- 用python写一个简单的爬虫功能
- 方正“四人帮”打造校内“利益生态圈”
- 【Python-matplotlib】画直方图(hist)