React Native中navigator.bluetooth.requestdevice()的等效实现方案咨询
针对从Web项目迁移到React Native时的蓝牙API适配需求,这里提供两种能最大化复用原有Web代码的方案:
1. 基于react-native-ble-manager封装适配Web逻辑
你已经尝试过react-native-ble-manager,可以通过封装让它的调用逻辑贴近Web的requestDevice():
核心封装代码
import BleManager from 'react-native-ble-manager'; import { useEffect, useState } from 'react'; // 初始化BLE模块(建议在根组件或使用蓝牙的组件中执行) useEffect(() => { BleManager.start({ showAlert: false }); // 可选:监听设备发现事件,用于实时更新设备列表 const discoverySub = BleManager.onDeviceDiscovered((device) => { // 可在这里更新本地设备列表状态 }); return () => { discoverySub.remove(); BleManager.stopScan(); }; }, []); // 模拟Web的requestDevice方法 const requestBluetoothDevice = async (options = {}) => { const { filters = [] } = options; // 启动扫描,参数依次为:目标服务UUID数组、扫描时长(秒)、是否允许重复扫描 await BleManager.scan([], 5, true); // 获取扫描到的所有设备,并根据filters过滤 const peripherals = await BleManager.getDiscoveredPeripherals(); const matchingDevices = peripherals.filter(peripheral => { if (filters.length === 0) return true; // 匹配filters中的服务UUID、名称前缀等条件,和Web API逻辑对齐 return filters.some(filter => { if (filter.services) { return filter.services.some(service => peripheral.serviceUUIDs?.includes(service)); } if (filter.namePrefix) { return peripheral.name?.startsWith(filter.namePrefix); } return false; }); }); await BleManager.stopScan(); // 这里可以改成弹出自定义选择框让用户选设备,而非直接返回第一个 if (matchingDevices.length > 0) { return matchingDevices[0]; } throw new Error('No matching Bluetooth device found'); };
调用时和Web端逻辑一致:
// 示例:请求包含特定服务UUID的设备 try { const device = await requestBluetoothDevice({ filters: [{ services: ['0000ffe0-0000-1000-8000-00805f9b34fb'] }] }); // 后续连接、读写操作复用原有Web逻辑(需适配成react-native-ble-manager的方法) } catch (err) { console.error(err); }
2. 使用react-native-web-bluetooth直接复用Web代码
这个库的设计目标就是对齐Web Bluetooth API,几乎可以零修改复用你原有的Web蓝牙代码:
步骤
- 安装依赖:
npm install react-native-web-bluetooth
- 配置原生权限:
- iOS:在
Info.plist中添加NSBluetoothAlwaysUsageDescription和NSBluetoothPeripheralUsageDescription字段,填写权限说明。 - Android:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />、<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />等必要权限(根据系统版本调整)。
- iOS:在
- 替换Web端的
navigator.bluetooth:
import { Bluetooth } from 'react-native-web-bluetooth'; // 初始化蓝牙实例 const bluetooth = new Bluetooth(); // 直接复用原有Web代码 const requestDevice = async () => { try { const device = await bluetooth.requestDevice({ filters: [{ services: ['0000ffe0-0000-1000-8000-00805f9b34fb'] }], optionalServices: ['0000ffe1-0000-1000-8000-00805f9b34fb'] // 可选服务 }); // 后续的设备连接、GATT操作和Web端完全一致 const server = await device.gatt.connect(); const service = await server.getPrimaryService('0000ffe0-0000-1000-8000-00805f9b34fb'); // ... 其他操作 } catch (error) { console.error('Request device failed:', error); } };
注意事项
- 权限申请:务必在原生端配置正确的蓝牙权限,否则会导致扫描失败或崩溃。
- 平台差异:Android 12及以上需要单独申请
BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限,iOS需要确保用户授权蓝牙访问。
内容的提问来源于stack exchange,提问作者Bhrugu Tundeliya
相关产品推荐
相关产品推荐

