Android 局域网内的多设备通信方式有多种,其中常见的方式有:
* 基于 TCP/UDP 的 Socket 通信
* 基于 Bluetooth 的近场通信
* 基于 Wifi 的 Wi-Fi Direct 连接
* 基于第三方框架的通信,如 MQTT、Websocket 等
每种方式都有其适用范围,下面分别介绍一下它们的示例代码、优劣势。
<>1. 基于 TCP/UDP 的 Socket 通信
Socket 是 TCP/UDP 套接字的抽象,通常用于实现网络上的应用程序通信。基于 Socket
的通信方式可以实现高效的传输,支持实时数据处理,其主要缺点是需要进行网络编程和网络拓扑发现。
下面是一个基于 TCP 的 Socket 通信示例,它通过创建一个服务器 Socket 和客户端 Socket 实现简单的数据传输:
// 服务器端代码 public class Server { public static void main(String[] args) throws
Exception { // 创建一个服务器 Socket,绑定到指定的端口 ServerSocket serverSocket = new
ServerSocket(8888); System.out.println("服务器已启动,等待客户端连接..."); // 等待客户端连接 Socket
socket= serverSocket.accept(); System.out.println("客户端已连接[" + socket.
getInetAddress().getHostAddress() + "]"); // 获取输入输出流 BufferedReader reader = new
BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriter
writer= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// 循环读取客户端发送的数据 while (true) { String data = reader.readLine(); System.out.
println("客户端发送了消息:" + data); // 发送响应消息给客户端 writer.write("服务端收到了消息[" + data + "]"
); writer.newLine(); writer.flush(); } } } // 客户端代码 public class Client { public
static void main(String[] args) throws Exception { // 创建一个 Socket 连接服务器 Socket
socket= new Socket("localhost", 8888); // 获取输入输出流 BufferedReader reader = new
BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriter
writer= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// 循环向服务器发送数据 while (true) { // 发送消息给服务器 writer.write("Hello, World!"); writer.
newLine(); writer.flush(); // 接收服务器响应消息 String data = reader.readLine(); System.
out.println("服务器返回了响应消息:" + data); Thread.sleep(1000); } } }
在上面的代码中,我们使用 Java 中的 ServerSocket 和 Socket 类来实现基于 TCP 的 Socket
通信。服务器端通过创建一个服务器 Socket 并等待客户端连接,收到连接请求后可以使用输入输出流来实现数据传输。客户端通过创建一个 Socket
向服务器发起连接,并使用输入输出流发送和接收数据。
<>2. 基于 Bluetooth 的近场通信
Bluetooth 是一种典型的无线短距离通信技术,它可以在近距离范围内实现设备之间的通信。Android 提供了 BluetoothAdapter 和
BluetoothSocket 等 API 来支持基于 Bluetooth
的通信,它们可以实现设备之间的数据传输、文件传输等功能。其主要缺点是受制于蓝牙信号的干扰和距离限制。
以下是一个基于 Bluetooth 的数据传输示例,它通过使用 BluetoothSocket 类实现数据传输:
// 服务端代码 public class ServerActivity extends AppCompatActivity { private static
final int REQUEST_ENABLE_BT = 123; private BluetoothAdapter bluetoothAdapter;
private BluetoothServerSocket serverSocket; private Thread acceptThread;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(
savedInstanceState); setContentView(R.layout.activity_server); // 初始化
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (
bluetoothAdapter== null) { Toast.makeText(this, "该设备不支持蓝牙", Toast.LENGTH_SHORT).
show(); return; } // 开启蓝牙 if (!bluetoothAdapter.isEnabled()) { Intent intent =
new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(
intent, REQUEST_ENABLE_BT); } // 服务端开启监听线程 acceptThread = new Thread(new
Runnable() { @Override public void run() { try { // 创建 BluetoothServerSocket
serverSocket= bluetoothAdapter.listenUsingRfcommWithServiceRecord(
"BluetoothServer", UUID.randomUUID()); while (true) { // 等待客户端连接 BluetoothSocket
clientSocket= serverSocket.accept(); Log.d("Server", "客户端已连接:" + clientSocket.
getRemoteDevice().getName()); // 获取输入输出流 InputStream inputStream = clientSocket.
getInputStream(); OutputStream outputStream = clientSocket.getOutputStream();
// 读取客户端发送的数据 BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream)); String data = reader.readLine(); Log.d("Server", "客户端发送的数据是:" +
data); // 发送响应给客户端 BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(outputStream)); writer.write("服务端收到了数据[" + data + "]");
writer.newLine(); writer.flush(); } } catch (IOException e) { e.printStackTrace(
); } } }); acceptThread.start(); } @Override protected void onDestroy() { super.
onDestroy(); // 关闭服务端 Socket if (serverSocket != null) { try { serverSocket.
close(); } catch (IOException e) { e.printStackTrace(); } } // 停止监听线程 if (
acceptThread!= null) { acceptThread.interrupt(); } } } // 客户端代码 public class
ClientActivity extends AppCompatActivity { private BluetoothAdapter
bluetoothAdapter; private BluetoothDevice serverDevice; private BluetoothSocket
socket; @Override protected void onCreate(Bundle savedInstanceState) { super.
onCreate(savedInstanceState); setContentView(R.layout.activity_client); //
查找蓝牙设备 bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); Set<
BluetoothDevice> devices = bluetoothAdapter.getBondedDevices(); for (
BluetoothDevice device : devices) { if ("BluetoothServer".equals(device.getName(
))) { serverDevice = device; break; } } if (serverDevice == null) { Toast.
makeText(this, "未找到配对设备", Toast.LENGTH_SHORT).show(); return; } // 连接蓝牙服务端 try {
socket= serverDevice.createRfcommSocketToServiceRecord(UUID.randomUUID());
socket.connect(); Log.d("Client", "连接服务器成功:" + socket.getRemoteDevice().getName(
)); // 获取输入输出流 InputStream inputStream = socket.getInputStream(); OutputStream
outputStream= socket.getOutputStream(); // 向服务端发送数据 BufferedWriter writer = new
BufferedWriter(new OutputStreamWriter(outputStream)); writer.write("Hello,
World!"); writer.newLine(); writer.flush(); // 读取服务端响应数据 BufferedReader reader =
new BufferedReader(new InputStreamReader(inputStream)); String data = reader.
readLine(); Log.d("Client", "服务端返回的响应:" + data); } catch (IOException e) { e.
printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy();
// 关闭客户端 Socket if (socket != null) { try { socket.close(); } catch (IOException
e) { e.printStackTrace(); } } } }
在上面的代码中,我们使用了 BluetoothAdapter 和 BluetoothSocket 类来实现基于 Bluetooth
的近场通信。服务端通过创建蓝牙服务器 Socket 并等待客户端连接,客户端通过创建一个蓝牙 Socket
连接服务器。在每次通信时,我们都通过输入输出流来发送和接收数据。
<>3. 基于 Wifi 的 Wi-Fi Direct 连接
Wi-Fi Direct 是一种 P2P 网络连接方式,它使用 Wi-Fi 技术来实现设备之间的直接通信。如果设备支持 Wi-Fi
Direct,我们可以使用 Android 提供的 WifiP2pManager 类并结合 WifiP2pManager.Channel 类来实现基于
Wi-Fi Direct 的通信。其主要优势是无需路由器就可以建立点对点连接,传输速度较快。缺点是目前有一定的兼容性限制,且Wi-Fi 信号干扰和距离限制较大。
以下是一个基于 Wi-Fi Direct 的数据传输示例,它使用 WifiP2pManager 和 WifiP2pManager.Channel
类来实现数据传输:
// 服务端代码 public class ServerActivity extends AppCompatActivity { private
WifiP2pManager wifiP2pManager; private WifiP2pManager.Channel channel; private
BroadcastReceiver receiver; private ServerSocket serverSocket; private Thread
acceptThread; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_server);
// 初始化 WifiP2pManager wifiP2pManager = (WifiP2pManager) getSystemService(Context
.WIFI_P2P_SERVICE); if (wifiP2pManager == null) { Toast.makeText(this, "该设备不支持
Wi-Fi Direct", Toast.LENGTH_SHORT).show(); return; } // 初始化 Channel channel =
wifiP2pManager.initialize(this, getMainLooper(), null); // 注册广播接收器 receiver =
new BroadcastReceiver() { @Override public 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) { Log.d("Server", "Wi-Fi Direct 已启用"); }
else { Log.d("Server", "Wi-Fi Direct 已停用"); } } else if (WifiP2pManager.
WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 设备列表发生变化 wifiP2pManager.
requestPeers(channel, new WifiP2pManager.PeerListListener() { @Override public
void onPeersAvailable(WifiP2pDeviceList peers) { for (WifiP2pDevice device :
peers.getDeviceList()) { Log.d("Server", "发现设备:" + device.deviceName + ", " +
device.deviceAddress); // 开始连接设备 if (device.deviceName.equals("client")) {
WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.
deviceAddress; wifiP2pManager.connect(channel, config, new WifiP2pManager.
ActionListener() { @Override public void onSuccess() { Log.d("Server", "连接设备成功")
; } @Override public void onFailure(int reason) { Log.d("Server", "连接设备失败:" +
reason); } }); } } } }); } else if (WifiP2pManager.
WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { // 连接状态发生变化 NetworkInfo
networkInfo= intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (
networkInfo.isConnected()) { // 建立连接 Log.d("Server", "连接已建立"); // 创建服务器 Socket
try { serverSocket = new ServerSocket(8888); Log.d("Server", "服务器 Socket 已创建");
} catch (IOException e) { e.printStackTrace(); } // 开启接收线程监听客户端连接 acceptThread =
new Thread(new Runnable() { @Override public void run() { while (true) { try {
// 等待客户端连接 final Socket socket = serverSocket.accept(); Log.d("Server",
"客户端已连接:" + socket.getInetAddress()); // 读取客户端发送的数据 BufferedReader reader = new
BufferedReader(new InputStreamReader(socket.getInputStream())); String data =
reader.readLine(); // 发送响应给客户端 BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())); writer.write("服务端收到了数据[" + data +
"]"); writer.newLine(); writer.flush(); } catch (IOException e) { e.
printStackTrace(); } } } }); acceptThread.start(); } else { // 断开连接 Log.d(
"Server", "连接已断开"); if (serverSocket != null) { try { serverSocket.close(); }
catch (IOException e) { e.printStackTrace(); } } if (acceptThread != null) {
acceptThread.interrupt(); } } } else if (WifiP2pManager.
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { // 本设备信息发生变化 WifiP2pDevice
device= intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); Log.d(
"Server", "本设备信息发生变化:" + device.deviceName + ", " + device.deviceAddress); } } }
; IntentFilter filter = new IntentFilter(); filter.addAction(WifiP2pManager.
WIFI_P2P_STATE_CHANGED_ACTION); filter.addAction(WifiP2pManager.
WIFI_P2P_PEERS_CHANGED_ACTION); filter.addAction(WifiP2pManager.
WIFI_P2P_CONNECTION_CHANGED_ACTION); filter.addAction(WifiP2pManager.
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); registerReceiver(receiver, filter); //
发现并连接设备 wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener(
) { @Override public void onSuccess() { Log.d("Server", "开始查找设备"); } @Override
public void onFailure(int reason) { Log.d("Server", "查找设备失败:" + reason); } }); }
@Override protected void onDestroy() { super.onDestroy(); // 关闭服务端 Socket if (
serverSocket!= null) { try { serverSocket.close(); } catch (IOException e) { e.
printStackTrace(); } } // 停止监听线程 if (acceptThread != null) { acceptThread.
interrupt(); } // 注销广播接收器 unregisterReceiver(receiver); } } // 客户端代码 public
class ClientActivity extends AppCompatActivity { private WifiP2pManager
wifiP2pManager; private WifiP2pManager.Channel channel; private
BroadcastReceiver receiver; private WifiP2pDevice serverDevice; private Socket
socket; @Override protected void onCreate(Bundle savedInstanceState) { super.
onCreate(savedInstanceState); setContentView(R.layout.activity_client); // 初始化
WifiP2pManager wifiP2pManager = (WifiP2pManager) getSystemService(Context.
WIFI_P2P_SERVICE); if (wifiP2pManager == null) { Toast.makeText(this, "该设备不支持
Wi-Fi Direct", Toast.LENGTH_SHORT).show(); return; } // 初始化 Channel channel =
wifiP2pManager.initialize(this, getMainLooper(), null); // 注册广播接收器 receiver =
new BroadcastReceiver() { @Override public 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) { Log.d("Client", "Wi-Fi Direct 已启用"); }
else { Log.d("Client", "Wi-Fi Direct 已停用"); } } else if (WifiP2pManager.
WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 设备列表发生变化 wifiP2pManager.
requestPeers(channel, new WifiP2pManager.PeerListListener() { @Override public
void onPeersAvailable(WifiP2pDeviceList peers) { for (WifiP2pDevice device :
peers.getDeviceList()) { Log.d("Client", "发现设备:" + device.deviceName + ", " +
device.deviceAddress); // 记录服务端设备 if (device.deviceName.equals("server")) {
serverDevice= device; } } } }); } else if (WifiP2pManager.
WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { // 连接状态发生变化 NetworkInfo
networkInfo= intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (
networkInfo.isConnected()) { // 建立连接 Log.d("Client", "连接已建立"); // 请求连接信息
wifiP2pManager.requestConnectionInfo(channel, new WifiP2pManager.
ConnectionInfoListener() { @Override public void onConnectionInfoAvailable(
WifiP2pInfo info) { if (info.groupFormed && info.isGroupOwner) { // 服务端不需要做额外处理
Log.d("Client", "该设备为服务端"); } else if (info.groupFormed) { // 客户端发起连接 Log.d(
"Client", "该设备为客户端"); try { socket = new Socket(); socket.connect(new
InetSocketAddress(serverDevice.deviceAddress, 8888), 5000); Log.d("Client",
"连接服务器成功:" + socket.getInetAddress()); // 向服务端发送数据 BufferedWriter writer = new
BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); writer.write(
"Hello, World!"); writer.newLine(); writer.flush(); // 读取服务端响应数据 BufferedReader
reader= new BufferedReader(new InputStreamReader(socket.getInputStream()));
String data = reader.readLine(); Log.d("Client", "服务端返回的响应:" + data); } catch (
IOException e) { e.printStackTrace(); } } } }); } else { // 断开连接 Log.d("Client",
"连接已断开"); if (socket != null) { try { socket.close(); } catch (IOException e) {
e.printStackTrace(); } } } } else if (WifiP2pManager.
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { // 本设备信息发生变化 WifiP2pDevice
device= intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); Log.d(
"Client", "本设备信息发生变化:" + device.deviceName + ", " + device.deviceAddress); } } }
; IntentFilter filter = new IntentFilter(); filter.addAction(WifiP2pManager.
WIFI_P2P_STATE_CHANGED_ACTION); filter.addAction(WifiP2pManager.
WIFI_P2P_PEERS_CHANGED_ACTION); filter.addAction(WifiP2pManager.
WIFI_P2P_CONNECTION_CHANGED_ACTION); filter.addAction(WifiP2pManager.
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); registerReceiver(receiver, filter); //
扫描设备 wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override public void onSuccess() { Log.d("Client", "开始查找设备"); } @Override
public void onFailure(int reason) { Log.d("Client", "查找设备失败:" + reason); } }); }
@Override protected void onDestroy() { super.onDestroy(); // 关闭客户端 Socket if (
socket!= null) { try { socket.close(); } catch (IOException e) { e.
printStackTrace(); } } // 注销广播接收器 unregisterReceiver(receiver); } }
在上面的代码中,我们使用了 WifiP2pManager 和 WifiP2pManager.Channel 类来实现基于 Wi-Fi Direct
的通信。服务端通过创建服务器 Socket 并等待客户端连接,客户端通过创建一个 Socket 连接服务器。在每次通信时,我们都通过输入输出流来发送和接收数据。
至此,我们介绍了 Android
中常见的几种局域网通信方式,并给出了示例代码。不同的通信方式有不同的适用场景和特点,开发者可以根据实际需求选择合适的通信方式进行开发。除了局域网通信,如果需要进行远程通信,可以使用云服务提供商的
API,比如阿里云、腾讯云、AWS 等。这些云服务提供商提供了丰富的服务和 API,可以满足不同的需求,比如对象存储、云数据库、虚拟机、消息队列等等。
以阿里云为例,可以使用阿里云的移动推送服务,实现消息的推送和设备间的通信。例如,我们可以使用阿里云移动推送 SDK
将消息推送给指定的设备或者设备群组,也可以使用自定义消息进行设备间的通信。推送服务的使用需要先在阿里云控制台创建应用,并配置相关参数,然后在客户端集成移动推送
SDK,根据文档进行 API 调用即可。
此外,阿里云还提供了多种云计算服务,可以用于搭建云服务器、存储数据、处理数据等等。比如,我们可以使用阿里云的云服务器 ECS 来搭建一个 Web
服务器,将自己的应用部署到云服务器上,并使用域名解析服务进行域名解析,实现较为稳定和可靠的远程通信。
当然,不同的云服务提供商提供的服务和 API
也有所不同,开发者可以根据需求进行选择。但无论是局域网通信还是云服务通信,都需要进行网络编程和安全认证,具有一定的复杂性。因此,建议在开发前仔细阅读文档,并根据需求进行合理的设计和实现。