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

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

相关文章:

  • 第33讲|遥感大模型在地学分类中的初探与实战
  • word选中所有的表格——宏
  • PostgreSQL数据库RPM方式安装详解
  • Python语法系列博客 · 第6期[特殊字符] 文件读写与文本处理基础
  • OCR技术与视觉模型技术的区别、应用及展望
  • 大学第一次笔记本清灰
  • 2.2/Q2,GBD数据库最新文章解读
  • 通过 Samba 服务实现 Ubuntu 和 Windows 之间互传文件
  • 单元测试的一般步骤
  • Linux操作系统--环境变量
  • PHP异常处理__Throwable
  • Vue 3 中将 ref 创建的响应式对象数据转换为普通(非响应式)的数据
  • 自动化测试相关协议深度剖析及A2A、MCP协议自动化测试应用展望
  • 基于大模型的下肢静脉曲张全流程预测与诊疗方案研究报告
  • [Swift]pod install成功后运行项目报错问题error: Sandbox: bash(84760) deny(1)
  • Django 实现服务器主动给客户端发送消息的几种常见方式及其区别
  • 医院科研科AI智能科研支撑平台系统设计架构方案探析
  • Java 动态代理教程(JDK 动态代理)(以RPC 过程为例)
  • 【java实现+4种变体完整例子】排序算法中【希尔排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
  • 从FPGA实现角度介绍DP_Main_link主通道原理
  • 上海市政府常务会议部署多措并举促进消费,提高居民收入,减轻家庭负担
  • 竹子砍了地却种不上,贵州赤水被指“整改复耕”存形式主义
  • GDP增长6.0%,一季度浙江经济数据出炉
  • 上海交大发布“AI十条”,鄂维南院士已任该校人工智能学院讲席教授
  • 95后男中音胡斯豪敲开芝加哥抒情歌剧院大门
  • 8个月女婴被指受虐后体重仅6斤?潮州警方:未发现虐待,父母有抚养意愿