介绍:蓝牙通信协议详解
1. 蓝牙协议分层
Android主要支持**经典蓝牙(Bluetooth Classic)和低功耗蓝牙(BLE)**两种模式:
-
经典蓝牙(BT 2.1/3.0+)
-
低功耗蓝牙(BLE 4.0+)
-
协议栈:GATT(通用属性协议)、ATT(属性协议)、L2CAP(逻辑链路控制)。
-
用途:IoT设备(传感器、手环)、间歇性数据传输。
-
带宽:约100 kbps,功耗极低。
-
——————————————————————————————————————————
一、BLE基础概念
低功耗蓝牙(Bluetooth Low Energy, BLE)是蓝牙4.0规范的核心部分,专为低功耗设备设计,具有以下特点:
-
低功耗:工作电流在微安级别,纽扣电池可工作数月甚至数年
-
快速连接:建立连接仅需几毫秒
-
简化协议栈:相比经典蓝牙更简单
-
有限数据传输:适合小数据量、间歇性传输场景
二、Android BLE支持情况
-
Android 4.3(API 18)开始支持BLE中心设备(Central)角色
-
Android 5.0(API 21)增加了外围设备(Peripheral)角色支持
-
Android 6.0(API 23)引入了更精细的位置权限控制
-
Android 8.0(API 26)优化了后台扫描限制
三、关键类与接口
-
BluetoothAdapter:代表本地蓝牙适配器
-
BluetoothLeScanner (API 21+):用于BLE设备扫描
-
ScanCallback:扫描结果回调
-
BluetoothDevice:代表远程蓝牙设备
-
BluetoothGatt:BLE连接和通信的核心类
-
BluetoothGattCallback:GATT操作回调
-
BluetoothGattService:GATT服务
-
BluetoothGattCharacteristic:GATT特征值
-
BluetoothGattDescriptor:GATT描述符
四、开发流程详解
1. 权限声明
<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"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
2. 检查BLE支持
// 检查设备是否支持BLE
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported", Toast.LENGTH_SHORT).show();
finish();
}
// 获取BluetoothAdapter
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
// 检查蓝牙是否开启
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
3. 扫描BLE设备
// Android 5.0+推荐使用BluetoothLeScanner
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
// 扫描设置
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
// 扫描过滤器(可选)
List<ScanFilter> filters = new ArrayList<>();
filters.add(new ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString(SERVICE_UUID))
.build());
// 开始扫描
scanner.startScan(filters, settings, scanCallback);
// 扫描回调
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
BluetoothDevice device = result.getDevice();
// 处理发现的设备
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
// 处理扫描失败
}
};
// 停止扫描
scanner.stopScan(scanCallback);
4. 连接设备与发现服务
// 连接GATT服务
BluetoothGatt gatt = device.connectGatt(context, false, gattCallback);
// 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) {
// 处理服务
}
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
// 特征值读取完成
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
// 特征值写入完成
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
// 特征值变化通知
}
};
5. 读写操作
// 读取特征值
boolean readSuccess = gatt.readCharacteristic(characteristic);
// 写入特征值
characteristic.setValue(data);
boolean writeSuccess = gatt.writeCharacteristic(characteristic);
// 启用通知
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
6. 断开连接与资源释放
// 断开连接
gatt.disconnect();
// 释放资源
gatt.close();
五、最佳实践与注意事项
-
权限处理:
-
Android 6.0+需要运行时请求位置权限
-
Android 12+需要明确请求BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限
-
-
扫描优化:
-
避免长时间连续扫描,会消耗大量电量
-
使用适当的扫描模式(SCAN_MODE_LOW_POWER/LOW_LATENCY/BALANCED)
-
在找到目标设备后立即停止扫描
-
-
连接管理:
-
连接超时处理(约30秒)
-
实现自动重连机制
-
正确处理连接状态变化
-
-
资源管理:
-
及时调用BluetoothGatt.close()释放资源
-
避免同时进行多个GATT操作
-
-
MTU协商:
-
在连接后协商最大传输单元(MTU)以提高吞吐量
gatt.requestMtu(MTU_SIZE);
-
-
后台限制:
-
Android 8.0+对后台扫描有限制
-
考虑使用前台服务进行长时间BLE操作
-
六、常见问题解决
-
扫描不到设备:
-
检查权限是否已授予
-
确认设备在广播
-
尝试不同的扫描模式
-
-
连接失败:
-
确保设备未被其他应用连接
-
检查设备是否支持BLE
-
尝试重置蓝牙适配器
-
-
数据传输不稳定:
-
缩短连接间隔(Connection Interval)
-
减少单次传输数据量
-
检查信号强度
-
-
Android 12兼容性:
-
更新权限声明
-
如果不需要定位,添加android:usesPermissionFlags="neverForLocation"
-
七、高级特性
-
扩展广播(Android 10+):
-
支持更长的广播数据
-
支持定期广播
-
-
LE Audio(Android 13+):
-
支持新的LE音频规范
-
提供更高质量的音频传输
-
-
Bluetooth 5特性:
-
2M PHY高速模式
-
长距离模式
-
广播扩展
-
通过以上详细指南,开发者可以全面掌握Android平台上低功耗蓝牙(BLE)的开发技术,构建高效、稳定的蓝牙应用。