项目场景:

在 UniApp 开发蓝牙设备联动应用(如智能硬件、设备控制、数据采集)时,蓝牙模块是兼容性问题最多、调试难度最大的功能之一。官方 API 封装虽简化了原生调用,但平台差异、权限机制、设备适配、连接稳定性等问题,很容易让新手踩坑。

本文基于 UniApp 官方 uni.openBluetoothAdapter 等蓝牙 API,适用APP 端(安卓 /iOS),小程序端逻辑基本通用,仅部分权限 / 生命周期略有差异。


问题1:iOS 蓝牙初始化成功,安卓直接报错 / 不执行回调

问题现象

调用 uni.openBluetoothAdapter 初始化蓝牙适配器:

  • iOS 端正常回调 success;
  • 安卓端直接无响应、报错 fail,或提示「未发现蓝牙适配器」。

原因分析:

1.安卓动态权限缺失:安卓 6.0+ 蓝牙需要位置权限、蓝牙扫描权限,仅配置清单文件无效;
2.安卓蓝牙依赖 GPS 开启:安卓 10 以下,蓝牙扫描必须打开 GPS,否则初始化 / 扫描失败;
3.部分安卓机蓝牙模块加载慢,未等待系统就绪就调用 API。

解决方案:

1.配置安卓权限

manifest.json → App 权限配置

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

2.初始化前先校验权限 + GPS

// 蓝牙初始化通用方法
async initBluetooth() {
  // 1. 先判断蓝牙是否可用
  const systemInfo = uni.getSystemInfoSync();
  if(systemInfo.platform === 'android'){
    // 安卓强制校验GPS
    const locationStatus = await this.checkAndroidGPS();
    if(!locationStatus){
      uni.showModal({title:'提示',content:'请打开手机GPS和位置权限'});
      return false;
    }
  }

  return new Promise((resolve) => {
    uni.openBluetoothAdapter({
      success: () => resolve(true),
      fail: (err) => {
        uni.showToast({title:'蓝牙初始化失败',icon:'none'});
        resolve(false);
      }
    })
  })
}

3.延迟重试

安卓机初始化失败后,延迟 500ms 重试一次。


问题2:扫描不到蓝牙设备,iOS 能扫到,安卓扫不到

问题现象

调用 uni.startBluetoothDevicesDiscovery 启动扫描,iOS 能正常发现设备,安卓列表为空。

原因分析:

  1. 安卓未授权位置权限,扫描直接被系统拦截;
  2. 扫描服务 UUID 填写错误 / 不填;
  3. 安卓后台限制扫描频率,扫描未持续执行。

解决方案:

1.动态申请位置权限

// 安卓扫描前申请权限
async requestAndroidPermission() {
  const status = await uni.requestPermissions({
    platform: 'android',
    permissions: ['android.permission.ACCESS_FINE_LOCATION']
  });
  return status[0] === 'authorized';
}

2.扫描时必须传入 services UUID

uni.startBluetoothDevicesDiscovery({
  services: ['0000ffe0-0000-1000-8000-00805f9b34fb'], // 硬件对应的服务UUID
  allowDuplicatesKey: false,
  success: () => {}
})

3.延迟停止

安卓扫描持续至少 2 秒,不要立即停止扫描。


问题3:连接设备提示 fail:connection fail/ 超时断开

问题现象

扫描到设备后调用 uni.createBLEConnection,直接报错连接失败,或连接后 1 秒自动断开。

原因分析:

  1. 设备地址问题:安卓用 deviceId 是 MAC 地址,iOS 是 UUID,直接混用会连接失败;
  2. 连接前未停止扫描,系统资源冲突;
  3. 设备已被其他手机绑定 / 连接;
  4. 服务 / 特征值未获取,连接流程不完整。

解决方案:

1.连接前必须停止扫描

// 标准连接流程
async connectDevice(deviceId) {
  // 第一步:停止扫描
  await uni.stopBluetoothDevicesDiscovery();
  // 第二步:创建连接
  return new Promise((resolve, reject) => {
    uni.createBLEConnection({
      deviceId,
      timeout: 10000,
      success: () => resolve(true),
      fail: (err) => reject(err)
    })
  })
}

2.严格使用 API 返回的 deviceId,不要手动修改 / 拼接;

3.延迟获取服务

连接成功后延迟 500ms 再获取服务,避免时序问题。


问题4:获取服务 / 特征值失败,提示 get service fail

问题现象

连接成功后,调用 uni.getBLEDeviceServicesuni.getBLEDeviceCharacteristics 失败,无法拿到特征值。

原因分析:

  1. 连接刚建立就调用 API,通信未就绪
  2. 设备服务 UUID 不匹配,硬件未正确广播;
  3. iOS 对服务获取有严格时序要求。

解决方案:

1.连接成功后加延迟(500ms~800ms)

2.遍历服务 + 特征值,不要硬编码索引

// 正确获取特征值
async getDeviceChar(deviceId) {
  const { services } = await uni.getBLEDeviceServices({ deviceId });
  // 遍历所有服务
  for (let service of services) {
    const { characteristics } = await uni.getBLEDeviceCharacteristics({
      deviceId,
      serviceId: service.uuid
    });
    // 找到可写/可读特征值
    const writeChar = characteristics.find(item => item.properties.write);
    const notifyChar = characteristics.find(item => item.properties.notify);
    if(writeChar && notifyChar) return { writeChar, notifyChar };
  }
}

问题5:开启 notify 失败,收不到设备返回的数据

问题现象

调用 uni.notifyBLECharacteristicValueChange 开启监听,回调成功,但设备发送数据时,APP 完全收不到。

原因分析:

  1. 特征值属性错误:开启 notify 必须用带有 notify/indicate 属性的特征值;
  2. 未监听 onBLECharacteristicValueChange 全局事件;
  3. iOS 必须先写descriptor才能正常接收数据(官方隐藏坑点)。

解决方案:

1.确保特征值支持 notify

2.提前注册全局监听

onLoad() {
  uni.onBLECharacteristicValueChange((res) => {
    // 接收设备数据
    const data = this.arrayBuffer2hex(res.value);
    console.log('收到数据:', data);
  })
}

更多推荐