上一篇
安卓实现wifi通信
- 行业动态
- 2025-04-21
- 4
基础概念与准备工作
在安卓设备中实现WiFi通信,主要涉及两种场景:
- WiFi P2P(Wi-Fi Direct):设备点对点直连,无需路由器。
- 传统WiFi网络通信:设备连接到同一WiFi热点后通过IP通信。
权限配置
在 AndroidManifest.xml
中声明必要权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <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" />
注意:安卓6.0+需动态申请 ACCESS_FINE_LOCATION
权限(因WiFi扫描依赖定位权限)。
WiFi P2P 实现步骤
初始化WiFi P2P
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); WifiP2pManager.Channel channel = manager.initialize(this, mainLooper, new WifiP2pManager.ChannelListener() { @Override public void onChannelDisconnected() { // 通道断开时回调 } });
注册BroadcastReceiver监听P2P状态
private final IntentFilter intentFilter = new IntentFilter(); public void onCreate() { intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); registerReceiver(receiver, intentFilter); } private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { // 处理WiFi P2P状态变化 } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 处理可用设备列表更新 } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { // 处理连接状态变化 } } };
发现设备并请求连接
// 发现设备 manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // 发现成功 } @Override public void onFailure(int reason) { // 失败处理 } }); // 连接目标设备 WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = targetDevice.deviceAddress; manager.connect(channel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // 连接成功 } @Override public void onFailure(int reason) { // 连接失败 } });
数据传输(Socket通信)
当连接建立后,系统会分配本地IP地址,可通过 ServerSocket
和 Socket
进行通信:
// 服务器端(接收方) ServerSocket serverSocket = new ServerSocket(8888); Socket socket = serverSocket.accept(); BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String message = reader.readLine(); // 读取数据 // 客户端(发送方) Socket socket = new Socket(targetIP, 8888); PrintWriter writer = new PrintWriter(socket.getOutputStream()); writer.println("Hello WiFi P2P"); // 发送数据
传统WiFi网络通信(同一热点下)
获取设备IP地址
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); String ipAddress = Formatter.formatIpAddress(wifiManager.getConnectionInfo().getIpAddress());
通过Socket通信
// 服务器端(监听端口) ServerSocket serverSocket = new ServerSocket(5000); Socket socket = serverSocket.accept(); DataInputStream dis = new DataInputStream(socket.getInputStream()); String data = dis.readUTF(); // 接收数据 // 客户端(连接服务器) Socket socket = new Socket("服务器IP", 5000); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeUTF("Hello WiFi"); // 发送数据
关键步骤与API对照表
步骤 | API/方法 | 权限 | 注意事项 |
---|---|---|---|
初始化WiFi P2P | WifiP2pManager.initialize() |
ACCESS_FINE_LOCATION |
需在主线程调用 |
发现设备 | WifiP2pManager.discoverPeers() |
需处理 WIFI_P2P_PEERS_CHANGED |
|
请求连接 | WifiP2pManager.connect() |
需对方接受连接 | |
获取连接信息 | WifiP2pInfo.groupOwnerAddress |
区分Group Owner和非Group Owner | |
传统WiFi通信(Socket) | Socket , ServerSocket |
INTERNET |
确保设备在同一局域网 |
相关问题与解答
问题1:WiFi P2P连接成功后如何判断自己是Group Owner?
解答:
在 onReceive()
中监听 WIFI_P2P_CONNECTION_CHANGED_ACTION
,通过 WifiP2pInfo
的 isGroupOwner
方法判断角色:
WifiP2pInfo info = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO); if (info.isGroupOwner) { // 当前设备是Group Owner,可启动ServerSocket } else { // 当前设备是Client,需连接Group Owner的IP }
问题2:传统WiFi通信中如何动态获取服务器IP?
解答:
- 服务器端在启动
ServerSocket
后,通过getLocalInetAddress()
或wifiManager.getConnectionInfo().getIpAddress()
获取IP。 - 客户端需提前知道服务器IP(可通过UI输入或广播通知)。
- 示例代码:
// 服务器获取IP InetAddress serverIp = InetAddress.getByName(wifiManager.getConnectionInfo().getIpAddress()); // 客户端连接 new Socket(serverIp, 5000);