一、什么是蓝牙通信
蓝牙(Bluetooth)是一种短距离无线通信技术,它的传输距离一般在10米以内,最高不超过100米。在现代生活中,蓝牙被广泛应用于手机、电脑、蓝牙音箱等设备的数据传输和控制。
蓝牙通信的特点是无需数据线连接两台设备,同时支持多设备同时连接,传输速率相对较慢但功耗低,稳定性较好。
二、蓝牙通信的实现技术
Android系统提供了Bluetooth API,使得开发者可以方便地实现蓝牙通信功能。
在蓝牙通信中,一般存在服务端和客户端两个角色。服务端负责创建蓝牙连接,等待客户端连接并接收客户端发送的数据。而客户端则负责搜索可用的服务端并向其发送数据。
在本文的蓝牙通信示例中,我们将演示如何在Android设备上实现蓝牙通信并通过蓝牙控制LED灯的开关。其中,一台设备将扮演服务端的角色,而另一台设备则作为客户端。
三、蓝牙通信示例代码
示例代码中,我们将在两个Activity中实现蓝牙通信功能。第一个Activity作为服务端,第二个Activity作为客户端。
服务端代码
private BluetoothAdapter mAdapter;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
private static final int STATE_NONE = 0; // we're doing nothing
private static final int STATE_LISTEN = 1; // now listening for incoming connections
private static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
private static final int STATE_CONNECTED = 3; // now connected to a remote device
public BluetoothService() {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
}
private synchronized void setState(int state) {
mState = state;
}
public synchronized int getState() {
return mState;
}
public synchronized void start() {
cancelConnectThread();
cancelConnectedThread();
if (mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
setState(STATE_LISTEN);
}
public synchronized void connect(BluetoothDevice device) {
cancelConnectThread();
cancelConnectedThread();
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
cancelConnectThread();
cancelConnectedThread();
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
setState(STATE_CONNECTED);
}
public synchronized void stop() {
cancelConnectThread();
cancelConnectedThread();
cancelAcceptThread();
setState(STATE_NONE);
}
public void write(byte[] out) {
ConnectedThread r;
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
r.write(out);
}
private void connectionFailed() {
setState(STATE_LISTEN);
}
private void connectionLost() {
setState(STATE_LISTEN);
}
private void cancelConnectThread() {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
private void cancelConnectedThread() {
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
}
private void cancelAcceptThread() {
if (mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord("BluetoothService", MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
while (mState != STATE_CONNECTED) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
e.printStackTrace();
break;
}
if (socket != null) {
connected(socket, socket.getRemoteDevice());
}
}
}
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp;
}
public void run() {
mAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException e) {
connectionFailed();
try {
mmSocket.close();
} catch (IOException e2) {
e2.printStackTrace();
}
BluetoothService.this.start();
return;
}
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(BluetoothState.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
connectionLost();
BluetoothService.this.start();
break;
}
}
}
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
mHandler.obtainMessage(BluetoothState.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码
private BluetoothAdapter mBluetoothAdapter;
private BluetoothService mBluetoothService;
private Button mBtnSwitch;
private boolean mLedOn = false;
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case BluetoothState.MESSAGE_READ:
break;
case BluetoothState.MESSAGE_WRITE:
break;
default:
break;
}
}
};
private void setupBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
setupService();
}
}
private void setupService() {
mBluetoothService = new BluetoothService(this, mHandler);
}
private void connectDevice(Intent data, boolean secure) {
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
mBluetoothService.connect(device);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, true);
}
break;
case REQUEST_ENABLE_BT:
if (resultCode == Activity.RESULT_OK) {
setupService();
} else {
Toast.makeText(this, "Bluetooth is not enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void switchLED() {
if (mLedOn) {
mBtnSwitch.setText(R.string.btn_led_on);
byte[] command = "0".getBytes();
mBluetoothService.write(command);
} else {
mBtnSwitch.setText(R.string.btn_led_off);
byte[] command = "1".getBytes();
mBluetoothService.write(command);
}
mLedOn = !mLedOn;
}
四、小结
本文介绍了蓝牙通信的基本概念和实现技术,并提供了Android设备上蓝牙通信的示例代码。通过示例代码,我们可以实现在两台Android设备之间进行蓝牙通信,并通过蓝牙控制LED灯的开关。