Android蓝牙关闭仍可扫描BLE设备:是系统漏洞还是未公开机制?
嘿,这个问题我做BLE应用时也踩过坑,一开始差点以为是系统漏洞,后来翻了官方文档和Android源码才搞清楚来龙去脉,给你梳理下:
用户看到的“蓝牙关闭”≠ 无线电完全禁用
咱们在系统设置或快速面板里关掉的蓝牙开关,很多时候只是关闭了蓝牙传统功能(比如配对耳机、传输文件),但低功耗蓝牙(BLE)的扫描功能可能被系统保留了——尤其是当你的应用持有BLUETOOTH_SCAN权限,并且在权限声明里加了android:usesPermissionFlags="neverForLocation"参数时。Android 12(API 31)之后引入了这个精细控制,允许应用在不开启全功能蓝牙的情况下,进行非位置用途的BLE扫描,而且系统不会在状态栏显示蓝牙图标,这就容易让用户误以为蓝牙完全关了。官方文档早有说明
这个行为并不是漏洞,Android官方在权限文档里明确提到:当BLUETOOTH_SCAN权限带有neverForLocation标记时,应用可以在蓝牙适配器未启用的情况下发起扫描,这种扫描被限制为“非位置相关”,系统会临时唤醒BLE无线电完成扫描,之后再静默关闭。额外验证小技巧
你可以在代码里加个判断:BluetoothAdapter.getDefaultAdapter().isEnabled(),如果返回false但仍能拿到扫描结果,那就是系统的临时扫描机制在起作用。另外检查下你的AndroidManifest.xml里的权限声明,是不是写了类似这样的代码:<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />如果是,那就是完全符合官方设计的行为。
另外补充一点:有些定制ROM可能会有自己的逻辑,比如为了支持IoT设备的后台联动,默认允许BLE扫描,但原生Android的核心逻辑就是上面说的那样。
内容的提问来源于stack exchange,提问作者Sam

