Android Beacon Library基于Intent的iBeacon扫描失效问题
问题分析与解决方案
intent-based scans的核心是通过系统广播触发扫描,而非应用自身持有扫描线程,你的配置缺少几个关键步骤,导致扫描无法正常工作,以下是修正方案:
必须补充的配置项
1. 注册系统广播接收器
intent-based scans依赖系统发送的扫描结果广播,需在AndroidManifest.xml中注册官方提供的BeaconIntentProcessor:
<receiver android:name="org.altbeacon.beacon.BeaconIntentProcessor" android:permission="android.permission.BLUETOOTH_SCAN"> </receiver>
2. 配置后台扫描权限与周期
- Android 12+必须声明并动态申请
BLUETOOTH_SCAN权限,若需后台扫描,需配合定位权限(部分设备要求)或在权限声明中添加android:usesPermissionFlags="neverForLocation"。 - 开启后台扫描周期优化,避免系统过度限制:
beaconManager.enableBackgroundScanPeriod(10000L, 5000L) // 扫描10秒,休眠5秒
3. 替换ViewModel为广播接收器接收状态
应用被杀后ViewModel会被销毁,observeForever无法接收回调,改用静态广播接收器处理监测事件:
自定义广播接收器
class BeaconMonitoringReceiver : BroadcastReceiver() { private val TAG = "BeaconReceiver" override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == BeaconManager.ACTION_MONITORING_EVENT) { val state = intent.getIntExtra(BeaconManager.EXTRA_MONITORING_STATE, MonitorNotifier.OUTSIDE) val region = intent.getParcelableExtra<Region>(BeaconManager.EXTRA_MONITORING_REGION) if (state == MonitorNotifier.INSIDE) { Log.d(TAG, "进入Beacon区域: $region") sendNotification(context!!) } else { Log.d(TAG, "离开Beacon区域: $region") } } } }
在Manifest中注册接收器
<receiver android:name=".BeaconMonitoringReceiver"> <intent-filter> <action android:name="org.altbeacon.beacon.MONITORING"/> </intent-filter> </receiver>
4. 修正初始化逻辑的时机
确保所有扫描配置在Application的onCreate中完成,这样应用被杀后由系统触发扫描时,初始化逻辑能正确执行:
override fun onCreate() { super.onCreate() val beaconManager = BeaconManager.getInstanceForApplication(this) BeaconManager.setDebug(true) val parser = BeaconParser() .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24") .setHardwareAssistManufacturerCodes(intArrayOf(0x004c)) beaconManager.beaconParsers.add(parser) // 开启intent-based扫描策略 beaconManager.setIntentScanningStrategyEnabled(true) // 配置后台扫描周期 beaconManager.enableBackgroundScanPeriod(10000L, 5000L) // 启动区域监测 try { beaconManager.startMonitoring(region) } catch (e: RemoteException) { e.printStackTrace() } }
关键注意事项
- intent-based scans的扫描调度由系统控制,无法像前台服务那样保证实时性,扫描间隔可能因系统省电策略被拉长。
- 应用被杀后,只有系统检测到匹配的Beacon区域时,才会唤醒应用触发广播接收器执行逻辑。
- 部分国产ROM(如小米、华为)有严格的后台限制,需手动将应用加入「后台白名单」或「自启动管理」,否则配置正确也无法触发扫描。
内容的提问来源于stack exchange,提问作者guti
相关产品推荐
相关产品推荐

