Android 局域网内的多设备通信方式有多种,其中常见的方式有:
每种方式都有其适用范围,下面分别介绍一下它们的示例代码、优劣势。
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 向服务器发起连接,并使用输入输出流发送和接收数据。
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 连接服务器。在每次通信时,我们都通过输入输出流来发送和接收数据。
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 也有所不同,开发者可以根据需求进行选择。但无论是局域网通信还是云服务通信,都需要进行网络编程和安全认证,具有一定的复杂性。因此,建议在开发前仔细阅读文档,并根据需求进行合理的设计和实现。