android wifi直连 wifip2pmanager

ops/2025/2/21 7:04:54/

android wifi直连 wifip2pmanager;使用WiFi 直连,然后通过udp进行通讯。
Android WiFi 直连(Wi-Fi Direct,也称为Wi-Fi P2P)是一种让两台或多台设备通过Wi-Fi技术直接进行点对点连接的技术,无需借助传统的无线路由器或接入点。这种技术使得设备间可以快速建立安全的无线连接,实现文件传输、屏幕共享、游戏对战等多种应用,尤其适用于智能手机、平板电脑、打印机、相机等消费电子设备间的近距离通信。

以下是Android WiFi 直连的基本工作原理和使用步骤:

工作原理:
设备发现:启用Wi-Fi Direct功能的设备可以通过广播信号搜索和发现附近的其他支持Wi-Fi Direct的设备。设备间可以互相检测到对方的存在,并显示在设备列表中供用户选择。

连接请求:用户在设备列表中选择要连接的目标设备后,发起连接请求。目标设备收到请求后,通常需要手动或自动确认接受连接。

组建立:一旦连接请求被接受,两台设备之间会自动建立一个Wi-Fi Direct组。在这个组中,一台设备会被选为“组主人”(Group Owner,GO),相当于小型网络的接入点,负责管理组内的连接和数据传输。另一台设备则作为“客户端”(Client)加入该组。

数据传输:连接建立后,组主人和客户端设备可以使用各自的IP地址和端口号进行直接的TCP/UDP通信。应用程序可以利用这些网络参数创建Socket连接,进行文件传输、消息传递等操作。

例子代码:

public class WifiConnectActivity extends AppCompatActivity {private Button btnConnect;private WifiDirectLink wifiDirectLink;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);LinearLayout linearLayout = new LinearLayout(this);linearLayout.setOrientation(LinearLayout.VERTICAL);setContentView(linearLayout);btnConnect = new AppCompatButton(this);btnConnect.setText("链接");AppCompatButton btnConnect2 = new AppCompatButton(this);btnConnect2.setText("发送");linearLayout.addView(btnConnect);linearLayout.addView(btnConnect2);wifiDirectLink = new WifiDirectLink(getApplicationContext());// 按钮点击事件 - 连接到对等设备btnConnect.setOnClickListener(v -> wifiDirectLink.connectToPeer());btnConnect2.setOnClickListener(v -> wifiDirectLink.send("hello".getBytes()));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.NEARBY_WIFI_DEVICES}, 119);} else {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 119);}}@Overrideprotected void onDestroy() {wifiDirectLink.release();super.onDestroy();}}

连接工具类:

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;import androidx.core.content.ContextCompat;import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;public class WifiDirectLink {private static final String TAG = "WifiDirectLink";private final WifiP2pManager wifiP2pManager;private final WifiP2pManager.Channel channel;private Context context;private final Handler handler = new Handler(Looper.getMainLooper());private SyncUDP udp;private String otherClientIp;public WifiDirectLink(Context context) {this.context = context;Log.i(TAG, "WifiDirectLink: begin start-----------------------------------------------");if (udp == null) {udp = new SyncUDP(Config.BROADCAST_PORT + 3);udp.setListener(this::receiveAction);}// 初始化Wi-Fi P2P管理器和通道wifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);channel = wifiP2pManager.initialize(context, Looper.getMainLooper(), null);// 创建意图过滤器并添加所需的意图动作IntentFilter intentFilter = new IntentFilter();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);// 注册广播接收器ContextCompat.registerReceiver(context, broadcastReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED);handler.postDelayed(new Runnable() {@Overridepublic void run() {try {discoverPeers();} catch (Exception e) {e.printStackTrace();}handler.postDelayed(this, 8888);}}, 88);}private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {Log.i(TAG, "onReceive: " + intent.getAction());String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {// 获取连接信息WifiP2pInfo wifiP2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);if (wifiP2pInfo != null) {new Thread(() -> {// 获取groupOwnerAddressInetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;// 在这里可以使用groupOwnerAddress进行相应的操作if (groupOwnerAddress != null) {String hostAddress = groupOwnerAddress.getHostAddress();String hostName = groupOwnerAddress.getHostName();byte[] address = groupOwnerAddress.getAddress();String canonicalHostName = groupOwnerAddress.getCanonicalHostName();Log.i(TAG, "onReceive: get host address:" + hostAddress + "; " + hostName + "; " + address + "; " + canonicalHostName);// start socket connectotherClientIp = hostAddress;if (!TextUtils.isEmpty(otherClientIp)) {new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context.getApplicationContext(), "获取鬣主任ip", Toast.LENGTH_LONG).show());}}}).start();}}}};public void send(byte[] buf) {// 广播 都接受得到Log.i(TAG, "send: other client ip:" + otherClientIp);if (udp == null || otherClientIp == null) return;new Thread(() -> {String substring = otherClientIp.substring(0, otherClientIp.lastIndexOf("."));substring = substring + ".255";udp.sendAction(buf, substring);}).start();}@SuppressLint("MissingPermission")public void discoverPeers() throws Exception {wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {Log.i(TAG, "onSuccess: scan wifi node");}@Overridepublic void onFailure(int i) {Log.i(TAG, "onFailure: No nodes scanned");}});}@SuppressLint("MissingPermission")public void connectToPeer() {Log.i(TAG, "connectToPeer: start connect");wifiP2pManager.requestPeers(channel, wifiP2pDeviceList -> {List<WifiP2pDevice> deviceList = new ArrayList<>(wifiP2pDeviceList.getDeviceList());Log.i(TAG, "connectToPeer: item count:" + deviceList.size());if (deviceList.size() == 0) {return;}for (WifiP2pDevice item : deviceList) {Log.i(TAG, "connectToPeer: item name:" + item.deviceName + "; " + item.deviceAddress);// 创建连接配置WifiP2pConfig config = new WifiP2pConfig();config.deviceAddress = item.deviceAddress;connectItem(config, item);}});}@SuppressLint("MissingPermission")private void connectItem(WifiP2pConfig config, WifiP2pDevice item) {try {wifiP2pManager.connect(channel, config, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {Log.i(TAG, "onSuccess: Link successful for:" + item.deviceName + "; " + item.deviceAddress);}@Overridepublic void onFailure(int reasonCode) {Log.i(TAG, "onFailure: Link failure for:" + item.deviceName + "; " + item.deviceAddress);}});} catch (Exception e) {e.printStackTrace();Log.i(TAG, "getDevices: connect item error:" + e.getMessage());}}private void receiveAction(byte[] buffer, int len, String ip) {Log.i(TAG, "receiveAction: ip:" + ip + "; len:" + len);}public void release() {handler.removeCallbacksAndMessages(null);if (udp != null) {udp.release();udp = null;}try {context.unregisterReceiver(broadcastReceiver);} catch (Exception e) {e.printStackTrace();Log.i(TAG, "release: error:" + e.getMessage());}try {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) channel.close();} catch (Exception e) {e.printStackTrace();Log.i(TAG, "release:close channel error:" + e.getMessage());}}
}

udp 通讯类:

import android.util.Log;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SyncUDP implements Runnable {private static final String TAG = "ReceiveUDP";private Thread thread;private DatagramSocket socket;private OnUpdateListener listener;private int port;public void setListener(OnUpdateListener listener) {this.listener = listener;}public void release() {if (thread != null && !thread.isInterrupted())thread.interrupt();listener = null;closeSocket();if (thread != null) {try {thread.join();} catch (Exception e) {e.printStackTrace();}thread = null;}}public SyncUDP(int port) {this.port = port;thread = new Thread(this);thread.start();}public void sendAction(byte[] buf, String ip) {if (socket == null || socket.isClosed()) return;try {DatagramPacket sendPacket = new DatagramPacket(buf, buf.length);sendPacket.setAddress(InetAddress.getByName(ip));sendPacket.setPort(port);socket.send(sendPacket);} catch (Exception e) {e.printStackTrace();Log.i(TAG, "sendAction: send package error:" + e.getMessage());}}@Overridepublic void run() {while (!Thread.interrupted()) {try {byte[] by = new byte[16];socket = new DatagramSocket(port);socket.setBroadcast(true);while (!Thread.interrupted()) {try {// receive dataDatagramPacket receivePacket = new DatagramPacket(by, by.length);Log.i(TAG, "run: start wait package");// Join threadsocket.receive(receivePacket);String ip = receivePacket.getAddress().getHostAddress();Log.i(TAG, "run: get package len:" + receivePacket.getLength() + "; ip:" + ip);if (listener != null)listener.onUpdateUI(receivePacket.getData(), receivePacket.getLength(), ip);} catch (Exception e) {e.printStackTrace();break;}}closeSocket();} catch (Exception e) {e.printStackTrace();}}closeSocket();}private void closeSocket() {if (socket != null) {if (!socket.isClosed()) {try {socket.close();} catch (Exception e) {e.printStackTrace();}}socket = null;}}public interface OnUpdateListener {void onUpdateUI(byte[] buffer, int len, String ip);}
}

http://www.ppmy.cn/ops/10513.html

相关文章

STM32F051C8T6 LQFP-48 ARM Cortex-M0 32位微控制器-MCU

STM32F051C8T6微控制器在物联网领域有诸多应用案例&#xff0c;以下是一些典型的应用场景&#xff1a; 1. 智能家居&#xff1a;在智能家居系统中&#xff0c;STM32F051C8T6可以用于控制智能家电&#xff0c;如智能灯具、智能门锁、智能空调等。通过无线通信模块&#xff08;…

CentOS 系统上使用 yum 安装 Nginx 及其模块

要在 CentOS 系统上使用 yum 安装 Nginx 及其 NJS (Nginx JavaScript Module)&#xff0c;首先需要确保你的系统已经包含了 Nginx 的官方仓库&#xff0c;因为 Nginx 的某些模块可能不在默认的软件仓库中。 以下是安装 Nginx 和 Nginx Module NJS 的基本步骤&#xff1a; 添加…

Linux(centos)服务器10秒快速配置Java环境

查看是否已安装Java java -version 查看yum能下载的Java版本 yum -y list java*这里选择安装Java 11 yum install -y java-11-openjdk.x86_64查看是否安装成功并配置到环境里 java -version结束

融合麻雀追随机制扰动与柯西变异的蜣螂优化算法,历史位置图,平均适应度收敛图一次性全部搞定,MATLAB代码...

本期文章复现一篇论文&#xff1a;《多策略改进的蜣螂优化算法及其应用》&#xff0c;该成果于2023年12月15日发表于中文核心期刊《计算机科学与探索》&#xff0c;参考文献如下&#xff1a; [1]郭琴,郑巧仙.多策略改进的蜣螂优化算法及其应用[J/OL].计算机科学与探索,1-22[202…

Nacos服务注册中心

1.引入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>2.application.properties中配置 # 应用名称 spring.application.namenacos-aserver…

HarmonyOS-静态库(SDK)的创建和使用

文章目录 一、静态库&#xff08;SDK&#xff09;二、创建静态库1.新建静态库模块2. 开发静态库内容3. 编译静态库 三、使用静态库1. 配置项目依赖2. 在应用中使用静态库3. 注意事项 四、打包错误1. library引用本地har包错误 一、静态库&#xff08;SDK&#xff09; 在Harmon…

政安晨:【深度学习神经网络基础】(九)—— 在深度学习神经网络反向传播训练中理解梯度

目录 简述 理解梯度 什么是梯度 计算梯度 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 简述 在深度…

计算机网络的基础知识

tcp叫段&#xff0c;udp叫报&#xff0c;ip叫包&#xff0c;链路层叫帧。 我们在网线中跑的就是帧。 tcp段和udp报没有长度限制&#xff0c;只有在ip层和链路层才有包和帧的最大限制。 一个tcp段&#xff0c;在tcp缓存区中被封装&#xff0c;然后传到ip层进行拆分和封装&#x…