当前位置: 首页 > ds >正文

Android 应用wifi direct连接通信实现

一. 打开Wi-Fi direct

1.必须启用Wi-Fi功能:在设备设置中开启Wi-Fi主开关(即使未连接路由器)
关闭冲突功能:若已开启「热点共享」或连接到其他Wi-Fi网络,需先关闭相关功能以避免硬件占.
<!-- Wi-Fi Direct 核心权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Android 10+ 需位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

1.1.代码调用打开WIFI
// 获取Wi-Fi管理器实例
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

// 开启Wi-Fi
if (!wifiManager.isWifiEnabled()) {
    wifiManager.setWifiEnabled(true); // API 28以下可调用,高版本需跳转系统设置页‌:ml-citation{ref="1,4" data="citationList"}
}

1.2.跳转系统Wi-Fi设置页(适用于无法直接控制Wi-Fi的情况)
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));

2.在系统设置中进入Wi-Fi菜单,点击右上角「高级」选项,找到并启用Wi-Fi Direct(部分设备显示为「WLAN直连」或「附近设备」)
3. 位置权限开关
Android 10及以上版本:需在设置中打开位置信息(GPS)权限,否则Wi-Fi Direct功能可能被禁用或无法扫描设备
动态权限申请:应用需通过弹窗申请ACCESS_FINE_LOCATION权限,用户需手动授

二.连接设备,数据通信

1.客户端设备处理

1.1 客户端注册广播监听

注册广播监听,包括:
#1.启用/禁用 Wi-Fi P2P 功能。
#2.扫描到附近的设备或者当设备处于可发现状态
#3.连接状态变化

WifiP2pManager manager = (WifiP2pManager) MyApplication.getAppContext().getSystemService(Context.WIFI_P2P_SERVICE);
WifiP2pManager.Channel channel = manager.initialize(MyApplication.getAppContext(), getMainLooper(), null);
// 客户端设备(主动发起连接的设备)注册广播接收器监听设备发现
private BroadcastReceiver clientReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {// 检查 Wi-Fi Direct 是否启用int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {// 功能已启用,一般是收到功能已启用执行1.设备发现discoverPeers();} else {// 功能未启用}} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {// 监听扫描到附近的设备或者当设备处于可发现状态(如其他设备开启 P2P 搜索或加入/退出网络)manager.requestPeers(channel, peerList -> {// 处理设备列表Collection<WifiP2pDevice> devices = peerList.getDeviceList();// 更新 UI 显示设备列表for (WifiP2pDevice device : devices) {//选择需要连接的WifiP2pDevice设备,clientConnectP2pDevice(MacAddress.fromString(device.deviceAddress));}});} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {//连接状态变化监听 如服务端接受连接并创建组后manager.requestConnectionInfo(channel, info -> {InetAddress groupOwnerAddress = info.groupOwnerAddress;if (info.groupFormed && !info.isGroupOwner) {// 客户端逻辑:连接群主 IP 的指定端口try {clientSocketConnect(context, groupOwnerAddress.getHostAddress());} catch (IOException e) {throw new RuntimeException(e);}} else if (info.isGroupOwner) {// 群主逻辑:启动服务端 Socket 这里是客户端不会处理这段}});}}
};/*** 客户端步骤1* 注册广播监听,包括:*  1.启用/禁用 Wi-Fi P2P 功能。*  2.扫描到附近的设备或者当设备处于可发现状态*  3.连接状态变化*/
private void clientRegisterWifiListen() {// 注册接收器IntentFilter intentFilter = new IntentFilter();//WIFI_P2P_STATE_CHANGED_ACTION监听 启用/禁用 Wi-Fi P2P 功能intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);MyApplication.getAppContext().registerReceiver(clientReceiver, intentFilter);
}

1.2 主动搜索设备

客户端在检查 Wi-Fi Direct已启用时,主动搜索设备

/*** 客户端步骤2* 客户端在检查 Wi-Fi Direct已启用时,主动搜索设备*/
private void discoverPeers() {manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {// 发现设备成功,客户端会收到WIFI_P2P_PEERS_CHANGED_ACTION广播}@Overridepublic void onFailure(int reason) {// 失败处理}});
}


1.3 选择设备连接

客户端在扫描到附近设备,选择设备连接

/*** 客户端步骤3* 客户端在扫描到附近设备,选择设备连接** @param targetDeviceAddress*/
private void clientConnectP2pDevice(MacAddress targetDeviceAddress) {WifiP2pConfig config = new WifiP2pConfig.Builder().setDeviceAddress(targetDeviceAddress).build();manager.connect(channel, config, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {//连接成功后}@Overridepublic void onFailure(int reason) {}});//发起 connect() 请求后,需验证连接是否成功建立manager.requestConnectionInfo(channel, info -> {InetAddress groupOwnerAddress = info.groupOwnerAddress;if (info.groupFormed && !info.isGroupOwner) {// 客户端逻辑:连接群主 IP 的指定端口try {clientSocketConnect(MyApplication.getAppContext(), groupOwnerAddress.getHostAddress());} catch (IOException e) {throw new RuntimeException(e);}} else if (info.isGroupOwner) {// 群主逻辑:启动服务端 Socket 这里是客户端不会处理这段}});
}


1.4 socket连接数据通信

客户端在监听到连接状态变化(服务端同意连接并创建组)获取到服务端ip地址和服务端创建的socket端口进行数据通信。

/*** 客户端步骤4* 客户端在监听到连接状态变化(服务端同意连接并创建组)获取到服务端ip地址和服务端* 创建的socket端口进行数据通信** @param context* @param serverIP* @throws IOException*/
private void clientSocketConnect(Context context, String serverIP) throws IOException {if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {return;}Socket socket = new Socket();socket.connect(new InetSocketAddress(serverIP, 8888));//连接之后就可以获取输入输出流进行 读写操作了InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream();
}

2.服务端设备处理

2.1 服务端注册广播监听

注册广播监听 连接状态变化(监听到客户端连接请求)

// 服务端(等待连接的设备)注册广播接收器
private final BroadcastReceiver p2pConnectReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);if (networkInfo.isConnected()) {// 连接已建立,处理群组信息(如群组所有者 IP 和角色)可进行数据传输} else {//服务端在收到连接请求后会默认成为组所有者并自动创建组。一般不需要调用acceptConnection//若需要确保服务端始终为组所有者(而非由系统自动协商决定),需手动调用 createGroup()acceptConnection();}}}
};/*** 服务端步骤1* 注册广播监听 连接状态变化(监听到客户端连接请求)*/
private void serverRegisterWifiListen() {// 服务端注册接收器IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);MyApplication.getAppContext().registerReceiver(p2pConnectReceiver, intentFilter);
}


2.2 接受连接创建群组

服务端如果接受连接后调用 WifiP2pManager.createGroup() 创建群组(作为群组所有者)
若设备需自动接受连接(如预配置场景),可直接调用 createGroup() 或响应连接请求

/*** 服务端步骤2* 服务端如果接受连接后调用 WifiP2pManager.createGroup() 创建群组(作为群组所有者)* 若设备需自动接受连接(如预配置场景),可直接调用 createGroup() 或响应连接请求*/
private void acceptConnection() {WifiP2pManager manager = (WifiP2pManager) MyApplication.getAppContext().getSystemService(Context.WIFI_P2P_SERVICE);WifiP2pManager.Channel channel = manager.initialize(MyApplication.getAppContext(), getMainLooper(), null);manager.createGroup(channel, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {//群组创建成功,被连接方成为群组所有者//此时客户端会收到WIFI_P2P_PEERS_CHANGED_ACTION广播,且可以获取到当前服务端的WifiP2pDevice对象//服务端创建socket 等待连接createServiceSocket();}@Overridepublic void onFailure(int reason) {// 处理失败逻辑(如显示错误提示)}});
}


2.3 创建服务端socket 和客户端通信

创建服务端socket等待客户端连接

/*** 服务端步骤3* 创建服务端socket等待客户端连接*/
private void createServiceSocket() {ServerSocket serverSocket = null;try {serverSocket = new ServerSocket(8888);Socket clientSocket = serverSocket.accept();//连接之后就可以获取输入输出流进行 读写操作了InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream();} catch (IOException e) {throw new RuntimeException(e);}
}

http://www.xdnf.cn/news/378.html

相关文章:

  • P3916 图的遍历
  • C语言学习之预处理指令
  • 【C++ Qt】信号和槽(内配思维导图 图文并茂 通俗易懂)
  • Java 动态代理教程(JDK 动态代理)(以RPC 过程为例)
  • 突破速率瓶颈:毫米波技术如何推动 5G 网络迈向极限?
  • Flink介绍——实时计算核心论文之Kafka论文总结
  • 用 R 语言打造交互式叙事地图:讲述黄河源区生态变化的故事
  • 毕业论文超清pdf带标签导出
  • CANFD技术在新能源汽车通信网络中的应用与可靠性分析
  • 【文件操作与IO】详细解析文件操作与IO (二)
  • PFC 是什么?
  • GN ninja 工程化构建例程
  • 定时器复习DSP【2025/4/18】
  • 项目之在线OJ
  • 工作督导 | 具有边缘型人格障碍倾向的高危来访者,咨询师如何应对?
  • 2025年危化品安全员考试题库及答案
  • 物联网平台管理系统
  • Origin LabTalk
  • rLLM - 使LLM的强化学习民主化
  • 用于数学定理和逻辑推理的符号系统
  • 【TVM教程】microTVM TFLite 指南
  • 从零开始学Python游戏编程31-类3
  • AI 数字短视频系统AI数字人源码开发:开启短视频行业发展新维度​
  • AUTOSAR图解==>AUTOSAR_SWS_E2ETransformer
  • 图像分类标注小工具
  • ABAP OLE
  • 『前端样式分享』联系我们卡片式布局 自适应屏幕 hover动效 在wikijs中使用 (代码拿来即用)
  • 使用Gone MCP 组件编写MCP Server
  • 《系统分析师-第三阶段—总结(一)》
  • LUN Capacity(Blocks) 是什么意思