Ionic Capacitor应用无法检测BLE设备(仅Android 13出现)
问题:Android 13设备上Ionic Capacitor应用无法检测到Beacon,系统却可以
我开发了一个基于Ionic Capacitor的应用,使用@capacitor-community/bluetooth-le插件。操作系统能检测到Beacon,但应用无法检测到,这个问题只出现在Android 13设备上。
环境信息
ionic info 输出
Ionic: Ionic CLI : 7.1.5 (/usr/local/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 7.5.5 @angular-devkit/build-angular : 17.0.1 @angular-devkit/schematics : 17.0.1 @angular/cli : 17.0.1 @ionic/angular-toolkit : 9.0.0 Capacitor: Capacitor CLI : 5.5.1 @capacitor/android : 5.5.1 @capacitor/core : 5.5.1 @capacitor/ios : not installed Utility: cordova-res (update available: 0.15.4) : 0.15.3 native-run (update available: 2.0.0) : 1.7.4 System: NodeJS : v20.9.0 (/usr/local/bin/node) npm : 10.1.0
Java版本
java version "1.8.0_361" Java(TM) SE Runtime Environment (build 1.8.0_361-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.361-b09, mixed mode)
代码片段(app.component.ts)
import { Component, OnInit } from '@angular/core'; import { Capacitor } from '@capacitor/core'; import { BleClient } from '@capacitor-community/bluetooth-le'; @Component({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['app.component.scss'], }) export class AppComponent implements OnInit { isLocationEnabled: any; isBLEEnabled: any; deviceId: any; ble: boolean = false; devices: any[] = []; response: any; constructor( ) {} async ngOnInit() { try { if (Capacitor.getPlatform() == 'android'){ this.isLocationEnabled = await BleClient.isLocationEnabled(); } else { this.isLocationEnabled = true; } await BleClient.initialize(); this.isBLEEnabled = await BleClient.isEnabled(); if (this.isBLEEnabled && this.isLocationEnabled) { this.ble = true; this.startScanning(); } } catch (error) { console.error(error) } } startScanning() { BleClient.requestLEScan({ allowDuplicates: false }, (res1) => { console.log('Device found', res1) }); } }
解决方案
1. 补充Android 13专属权限
Android 13对BLE扫描新增了独立权限控制,需在AndroidManifest.xml中添加:
<!-- Android 13+ 必需的BLE扫描权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- Beacon扫描依赖定位,需添加精细定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 若需后台扫描,需补充后台定位权限 --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
2. 动态申请权限
Android 13要求BLUETOOTH_SCAN和定位权限必须在运行时动态申请,修改ngOnInit逻辑:
import { PermissionState, Permissions } from '@capacitor/core'; async ngOnInit() { try { if (Capacitor.getPlatform() === 'android') { // 申请BLE扫描权限 const scanPerm = await Permissions.request({ permissions: ['android.permission.BLUETOOTH_SCAN'], }); // 申请精细定位权限 const locPerm = await Permissions.request({ permissions: ['android.permission.ACCESS_FINE_LOCATION'], }); // 检查权限是否通过 if (scanPerm['android.permission.BLUETOOTH_SCAN'] !== PermissionState.Granted || locPerm['android.permission.ACCESS_FINE_LOCATION'] !== PermissionState.Granted) { console.error('缺少必要权限,无法扫描BLE设备'); return; } this.isLocationEnabled = await BleClient.isLocationEnabled(); } else { this.isLocationEnabled = true; } await BleClient.initialize(); this.isBLEEnabled = await BleClient.isEnabled(); if (this.isBLEEnabled && this.isLocationEnabled) { this.ble = true; this.startScanning(); } } catch (error) { console.error(error); } }
3. 优化扫描配置
Android 13对无过滤的BLE扫描限制更严格,建议添加Beacon的服务UUID过滤,减少扫描负载:
startScanning() { BleClient.requestLEScan( { allowDuplicates: false, services: ['YOUR_BEACON_UUID'] // 替换为你的Beacon专属UUID }, (res1) => { console.log('Device found', res1); } ); }
4. 检查后台扫描限制
若应用需要在后台持续扫描Beacon,除了添加ACCESS_BACKGROUND_LOCATION权限,还需确保应用处于前台服务状态,避免被系统限制扫描频率。
内容的提问来源于stack exchange,提问作者Alvaro Cortizo
相关产品推荐
相关产品推荐

