create-react-native-app蓝牙开发指南:与硬件设备通信
你是否在使用create-react-native-app开发蓝牙应用时遇到设备连接不稳定、数据传输延迟或权限配置混乱等问题?本文将从环境搭建到实际通信,手把手教你使用react-native-ble-plx库实现手机与硬件设备的稳定通信,读完后你将掌握:蓝牙设备扫描、连接管理、数据读写的完整流程,以及iOS/Android双平台权限配置技巧。
开发环境准备
安装蓝牙依赖库
react-native-ble-plx是目前React Native生态中最成熟的蓝牙开发库,支持BLE(Bluetooth Low Energy,蓝牙低功耗)设备通信。通过create-react-native-app创建的项目需先安装该依赖:
# 使用npm安装
npm install react-native-ble-plx --save
# 或使用yarn安装
yarn add react-native-ble-plx
平台权限配置
蓝牙功能需要配置系统权限,不同平台的配置方式不同:
iOS平台配置
- 在
ios/项目名/Info.plist中添加蓝牙权限描述:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>需要蓝牙权限以连接智能硬件设备</string>
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string> <!-- 允许后台蓝牙通信 -->
</array>
- 确保Xcode中开启蓝牙后台模式:
- 打开
ios/项目名.xcworkspace - 进入项目设置 → Signing & Capabilities → 添加
Background Modes - 勾选
Uses Bluetooth LE Accessories
Android平台配置
- 在
android/app/src/main/AndroidManifest.xml中添加权限:
<!-- 基础蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Android 12+ 蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 位置权限(用于蓝牙扫描) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
- 在
android/build.gradle中确保最低SDK版本不低于23:
buildscript {
ext {
minSdkVersion = 23 // BLE功能要求至少API 23
}
}
蓝牙通信核心流程
初始化蓝牙管理器
创建BluetoothManager.ts封装蓝牙操作,通过BleManager类初始化蓝牙客户端:
import { BleManager, Device } from 'react-native-ble-plx';
class BluetoothManager {
private manager: BleManager;
constructor() {
// 初始化蓝牙管理器
this.manager = new BleManager({
restoreStateIdentifier: 'ble-manager-state',
restoreStateFunction: (state) => {
// 恢复蓝牙连接状态(用于应用重启后重连)
if (state) {
console.log('蓝牙状态已恢复', state);
}
}
});
}
// 检查蓝牙是否开启
async checkBluetoothEnabled(): Promise<boolean> {
const state = await this.manager.state();
return state === 'PoweredOn';
}
}
export const bluetoothManager = new BluetoothManager();
扫描蓝牙设备
使用startDeviceScan方法扫描周围的BLE设备,需注意扫描会消耗设备电量,建议设置超时自动停止:
// 在BluetoothManager类中添加扫描方法
async scanDevices(timeoutMs: number = 5000): Promise<Device[]> {
return new Promise((resolve, reject) => {
const devices: Device[] = [];
const scanSubscription = this.manager.startDeviceScan(
null, // 扫描所有服务UUID的设备(传入特定UUID可过滤设备)
{ allowDuplicates: false }, // 不重复返回已发现设备
(error, device) => {
if (error) {
scanSubscription.remove();
reject(error);
return;
}
if (device && !devices.some(d => d.id === device.id)) {
devices.push(device);
console.log('发现设备:', device.name, device.id);
}
}
);
// 超时后停止扫描
setTimeout(() => {
scanSubscription.remove();
resolve(devices);
}, timeoutMs);
});
}
连接蓝牙设备
扫描到设备后,通过设备ID建立连接,连接过程需处理可能的异常(如设备超出范围、连接超时等):
// 在BluetoothManager类中添加连接方法
async connectToDevice(deviceId: string): Promise<Device> {
try {
const device = await this.manager.connectToDevice(deviceId, {
autoConnect: false, // 不自动重连(需要时手动处理)
timeout: 15000 // 15秒连接超时
});
// 连接成功后发现设备服务
await device.discoverAllServicesAndCharacteristics();
return device;
} catch (error) {
console.error('设备连接失败:', error);
throw error;
}
}
读写设备数据
BLE设备通过GATT(Generic Attribute Profile)协议通信,数据存储在"特征值(Characteristic)"中,读写流程如下:
// 读取特征值数据
async readCharacteristic(
deviceId: string,
serviceUuid: string,
characteristicUuid: string
): Promise<Buffer> {
const device = await this.manager.getDevice(deviceId);
const characteristic = await device.readCharacteristicForService(
serviceUuid,
characteristicUuid
);
return characteristic.value as Buffer; // 数据以Buffer格式返回
}
// 写入数据到特征值
async writeCharacteristic(
deviceId: string,
serviceUuid: string,
characteristicUuid: string,
data: Buffer
): Promise<void> {
const device = await this.manager.getDevice(deviceId);
await device.writeCharacteristicWithoutResponseForService(
serviceUuid,
characteristicUuid,
data.toString('base64') // 数据需转换为base64字符串
);
}
完整通信示例
以下是一个连接温湿度传感器并读取数据的完整示例,假设传感器的服务UUID为0000FFB0-0000-1000-8000-00805F9B34FB,特征值UUID为0000FFB2-0000-1000-8000-00805F9B34FB:
// 温湿度传感器通信示例
async function readTemperatureHumidity() {
try {
// 1. 检查蓝牙是否开启
const isEnabled = await bluetoothManager.checkBluetoothEnabled();
if (!isEnabled) {
console.log('请开启蓝牙');
return;
}
// 2. 扫描设备(超时5秒)
const devices = await bluetoothManager.scanDevices(5000);
const sensorDevice = devices.find(d => d.name?.includes('TempSensor'));
if (!sensorDevice) {
console.log('未找到温湿度传感器');
return;
}
// 3. 连接设备
await bluetoothManager.connectToDevice(sensorDevice.id);
// 4. 读取温湿度数据
const serviceUuid = '0000FFB0-0000-1000-8000-00805F9B34FB';
const characteristicUuid = '0000FFB2-0000-1000-8000-00805F9B34FB';
const data = await bluetoothManager.readCharacteristic(
sensorDevice.id,
serviceUuid,
characteristicUuid
);
// 5. 解析数据(假设数据格式为:温度(2字节小端) + 湿度(2字节小端))
const temperature = data.readInt16LE(0) / 10; // 温度值,精度0.1℃
const humidity = data.readInt16LE(2) / 10; // 湿度值,精度0.1%
console.log(`当前温度: ${temperature}℃, 湿度: ${humidity}%`);
} catch (error) {
console.error('通信失败:', error);
}
}
常见问题解决方案
设备连接不稳定
- 问题原因:蓝牙信号受环境干扰,或设备进入休眠模式
- 解决方法:
- 实现连接状态监听,断线时自动重连:
device.onDisconnected((error, device) => { console.log('设备已断开连接,尝试重连...'); this.connectToDevice(device.id); // 调用之前实现的连接方法 });- 增加扫描功率(仅Android支持):
await this.manager.setScanMode(2); // 2表示高功率扫描
数据传输缓慢
- 问题原因:默认MTU(Maximum Transmission Unit,最大传输单元)值较小(通常20字节)
- 解决方法:协商更大的MTU值(最大512字节):
async negotiateMtu(deviceId: string, mtu: number = 512): Promise<number> {
const device = await this.manager.getDevice(deviceId);
return device.requestMtu(mtu);
}
权限申请被拒
- 问题原因:用户拒绝授予位置或蓝牙权限
- 解决方法:使用
react-native-permissions库检查并请求权限:
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';
async requestBluetoothPermissions() {
if (Platform.OS === 'ios') {
const result = await check(PERMISSIONS.IOS.BLUETOOTH_ALWAYS);
if (result !== RESULTS.GRANTED) {
await request(PERMISSIONS.IOS.BLUETOOTH_ALWAYS);
}
} else {
// Android需要位置和蓝牙权限
await request(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
await request(PERMISSIONS.ANDROID.BLUETOOTH_SCAN);
}
}
总结与展望
本文介绍了使用create-react-native-app和react-native-ble-plx库开发蓝牙应用的核心流程,包括设备扫描、连接管理、数据读写等关键步骤,并提供了跨平台权限配置和常见问题解决方案。蓝牙开发中,设备兼容性和环境干扰是主要挑战,建议在多台设备上测试,并实现完善的错误处理机制。
未来,你可以进一步探索:
- 蓝牙广播包解析(用于识别设备类型)
- 低功耗优化(如批量发送数据、合理设置扫描间隔)
- 复杂设备的多特征值协同操作
希望本文能帮助你顺利开发出稳定可靠的蓝牙应用,如有疑问欢迎在评论区留言讨论!
点赞收藏本文,关注作者获取更多React Native开发技巧,下期将分享蓝牙设备OTA固件升级实战教程。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



