Connecting with Wi-Fi Direct

2024-02-17 00:58
文章标签 connecting direct wi fi

本文主要是介绍Connecting with Wi-Fi Direct,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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);

}

From: http://blog.sina.com.cn/s/blog_819100560101a86s.html
LINUX\android\development\samples\WiFiDirectDemo
android 4.4 下 相关的p2p代码在frameworks/base/wifi/java/android/net/wifi/p2p/

这篇关于Connecting with Wi-Fi Direct的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SAP MM模块与FI模块集成之科目配置

1. 定义评估范围 OMWD   评估范围设置在工厂层,那么系统自动建立和工厂具有相同ID的评估范围 IMG:物料管理>评估和科目设置>科目确定>无向导的科目确定>将评估范围群集分组 提示:评估层级——评估分组代码——评估范围。 2. OBYC-BSX(存货科目) IMG:物料管理->评估和科目设置->科目确定->无向导的科目确定->配置自动记帐 双击BSX,输入科目表。

2024.09.04【读书笔记】|如何使用Tombo进行Nanopore Direct RNA-seq(DRS)分析

文章目录 Tombo快速使用介绍模型介绍RNA修饰分析步骤特异性替代碱基检测(推荐)De novo canonical model comparison ONT全长转录组分析步骤疑难解答Minimap2在比对nanopore直接RNA-seq数据时的最佳实践和参数设置有哪些?featureCounts在进行RNA-seq定量分析时,如何选择最合适的参考基因组注释文件?Tombo序列重校正过程

畅游5G高速网络:联发科集成Wi-Fi6E与蓝牙5.2的系统级单芯片MT7922

这周末,除非外面下钞票,否则谁也拦不住我玩《黑神话悟空》(附:两款可以玩转悟空的显卡推荐) IPBrain平台君 集成电路大数据平台 2024年09月03日 17:28 北京 联发科一直以创新技术追赶市场需求…… “不努力向前游就会被海浪拍回岸边…” 芯片设计公司产品层出不穷,想要站稳脚根只有不断创新其技术和适应市场的需求。来自台湾地区的联发科技,自

公共Wi-Fi,黑客如影随形之——三大阴招

其实在2014年让大家对 Wi-Fi 最担心的就是安全问题,这个是最困扰用户和商家的,小编今天就来给各位总结黑客最常见的三大“阴招”。以后各位到公共场所最好还是避免有支付等隐私操作! NO.1——域名劫持。   用手机连上了一个不设密码的Wi-Fi后,输入正确的工商银行网站,跳出的网页却是个与之相似度很高的山寨钓鱼网站。 在当前的Wi-Fi环境下,黑客可以进入无线路由器的管理

浅谈Buffer I/O 和 Direct I/O

通常来说,文件I/O可以分为两种: Buffer I/ODirect I/O Buffer I/O 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。 在 Linux 的缓存 I/O 机制中,这种访问文件的方式是通过两个系统调用实现的:read() 和 write()。调用read()时,如果 操作系统内核地址空间的页缓存( page cache )

nginx 出错:socket() failed (24: Too many open files) while connecting to upstream

1. 错误描述 通过nginx负载两个节点的rabbitmq 当用java代码创建超过500个连接时(我的机器默认只能创建这么多),出现错误: com.rabbitmq.client.ShutdownSignalException: connection errorjava.net.SocketException: Software caused connection abort: recv

RTX3060Ti + Intel Wi-fi 6 AX201 + 512G SSD 2T HD 台式机 双系统 Ubuntu 16.04 安装 + Qt catkin cmake 开发环境部署

目录 Ubuntu 16.04系统安装: RTX3060Ti显卡驱动安装: 其他软件环境的安装: 无线网卡驱动安装: 升级内核: Qt 的安装 catkin安装: CMake安装: Git安装: SVN安装: 搜狗输入法的安装: Ubuntu 16.04系统安装: Ubuntu 16.04系统盘制作就先不多说了,后续有时间的时候再详细补充 具体可参考:Ubunt

深入理解DPO(Direct Preference Optimization)算法

目录 1. 什么是DPO?2. Bradley-Terry模型2.1 奖励模型的训练 3. 从PPO到DPO4. DPO的简单实现5. 梯度分析Ref 1. 什么是DPO? 直接偏好优化(Direct Preference Optimization, DPO)是一种不需要强化学习的对齐算法。由于去除了复杂的强化学习算法,DPO 可以通过与有监督微调(SFT)相似的复杂度实现模型对

SAP FI模块开发

1. SAP FI模块财务主数据管理 2. 总账核算

Wi-Fi发射功率简介

目录 一、概念  1.1 射频发射与组合功率 1.2 天线增益 1.3 信道影响 二、常用单位及转换 2.1 dB 与 dBm 2.2 dBi 与 dBd 三、发射功率 3.1 发射功率调节 3.1.1 TPC 3.2 国家码与信道功率 一、概念  ① 和 ⑦ 表示射频发送端处的功率,单位是 dBm。其中 ① 表示AP端的射频发射功率,⑦ 表示无线终端