一、什麼是藍牙通信
藍牙(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燈的開關。
原創文章,作者:TDIS,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/147602.html