Android 平台提供了完整的蓝牙 API,支持
传统蓝牙(Bluetooth Classic)和低功耗蓝牙(BBluetooth Low Energy, BLE)两种通信方式。
以下是开发蓝牙应用的关键知识点。
1. 基本概念
传统蓝牙(Bluetooth Classic)
-
适合大流量数据传输(如音频、文件传输)
-
典型协议: RFCOMM(串口模拟), A2DP(音频), HFP(免提)等
低功耗蓝牙(BLE)
-
适合间歇性小数据量传输,功耗低
-
典型应用: 健康设备、传感器、信标(Beacon)
2. 开发准备
清单文件配置
<!-- 蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- 蓝牙扫描需要的位置权限(Android 6.0+) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 仅用于Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- 声明蓝牙功能 -->
<uses-feature android:name="android.hardware.bluetooth" android:required="true" />
运行时权限请求(Android 6.0+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}
3. 传统蓝牙开发
检查并启用蓝牙
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 检查设备是否支持蓝牙
if (bluetoothAdapter == null) {
// 设备不支持蓝牙
return;
}
// 检查蓝牙是否启用,如果未启用则请求启用
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
发现设备
// 注册广播接收器监听发现的设备
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
// 开始发现设备
bluetoothAdapter.startDiscovery();
// 广播接收器示例
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceAddress = device.getAddress();
// 处理发现的设备
}
}
};
// 停止发现
bluetoothAdapter.cancelDiscovery();
客户端连接(作为客户端)
// 假设已获取到BluetoothDevice对象
BluetoothDevice device = ...;
// 使用UUID创建RFCOMM连接
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // 标准串口UUID
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid);
// 连接
try {
socket.connect();
// 连接成功,获取输入输出流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 进行数据读写
outputStream.write("Hello".getBytes());
byte[] buffer = new byte[1024];
int bytes = inputStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
} finally {
socket.close();
}
服务端监听(作为服务端)
// 创建监听socket
BluetoothServerSocket serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(
"MyBluetoothApp", uuid);
// 接受连接(应在后台线程执行)
try {
BluetoothSocket socket = serverSocket.accept();
// 连接建立,处理通信
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 通信处理...
} catch (IOException e) {
e.printStackTrace();
} finally {
serverSocket.close();
}
4. 低功耗蓝牙(BLE)开发
初始化BLE
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
// 检查BLE支持
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
// 设备不支持BLE
return;
}
// 启用蓝牙(同传统蓝牙)
扫描BLE设备
// BLE扫描回调
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
String deviceName = device.getName();
String deviceAddress = device.getAddress();
// 处理发现的设备
}
};
// 开始扫描
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
List<ScanFilter> filters = new ArrayList<>(); // 可选过滤条件
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
scanner.startScan(filters, settings, scanCallback);
// 停止扫描
scanner.stopScan(scanCallback);
连接BLE设备
// 蓝牙GATT回调
private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
// 连接成功,发现服务
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
// 连接断开
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// 服务发现完成,可以读写特征值
List<BluetoothGattService> services = gatt.getServices();
for (BluetoothGattService service : services) {
List<BluetoothGattCharacteristic> characteristics =
service.getCharacteristics();
// 处理特征值
}
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
// 特征值读取完成
byte[] data = characteristic.getValue();
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
// 特征值写入完成
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
// 特征值通知数据到达
byte[] data = characteristic.getValue();
}
};
// 连接设备
BluetoothDevice device = ...; // 从扫描结果获取
BluetoothGatt gatt = device.connectGatt(context, false, gattCallback);
// 断开连接
gatt.disconnect();
gatt.close();
读写BLE特征值
// 获取特征值对象(通常在onServicesDiscovered回调中)
BluetoothGattCharacteristic characteristic = ...;
// 读取特征值
gatt.readCharacteristic(characteristic);
// 写入特征值
characteristic.setValue("Hello".getBytes());
gatt.writeCharacteristic(characteristic);
// 启用通知
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); // 客户端特征配置描述符
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
5. 常见问题
-
权限问题:确保正确声明和请求所有必要权限
-
蓝牙可用性:检查设备是否支持蓝牙/BLE功能
-
连接稳定性:处理连接断开和重连逻辑
-
线程管理:蓝牙操作应在后台线程执行
-
Android版本差异:不同Android版本API和行为可能有差异
6. 推荐库
-
Android-BLE-Library:简化BLE开发
-
FastBle:Android BLE框架
-
BluetoothHelper:传统蓝牙开发辅助库
结束。