Android 12:BLE扫描找不到任何设备。

10

我正在尝试将一个连接到自定义物理设备的Bluetooth Low Energy应用程序升级到Android 12。我已按照文档中的说明设置了所有内容,但它没有起作用。

权限:

<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BILLING" />

<uses-feature
    android:name="android.hardware.bluetooth_le"
    android:required="true" />

代码:

private final ScanCallback scanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        Log.d(TAG, "Scan result!");
    }

    @Override
    public void onScanFailed(int errorCode) {
        Log.w(TAG, "Scan failed: " + errorCode);
    }
};

public void start() {
    bluetoothLeScanner.startScan(scanCallback);
}

我还使用ActivityResultContracts.RequestMultiplePermissions()协议请求权限。日志显示权限已设置。
当我调用start()方法时,onScanResult(...)方法从未被调用。当我切换到安装了Android 11的设备时,则能正常工作。当我启动BLE扫描器应用程序(来自Play商店)时,它会找到该设备。
更新:当我将目标SDK设置回30时,一切正常(当然,旧的权限等等也是如此)。
有人遇到过同样的问题或解决过吗?非常感谢任何建议。
谢谢!

BLUETOOTH_ADVERTISEBLUETOOTH_CONNECTBLUETOOTH_SCAN是运行时权限,因此应用程序必须明确请求用户批准。我在你的片段中没有看到这一点。更多信息请参见:https://developer.android.com/guide/topics/connectivity/bluetooth/permissions - Risto
我假设你的目标SDK是31(安卓12)? - Michael Kotzjan
1
嗨,@MichaelKotzjan,我的目标SDK是31,我为了测试目的将其更改为32。 - Lukas Fink
也许你可以在这个帖子中找到一些答案:https://dev59.com/OlEG5IYBdhLWcg3wVapJ - dgp
嘿@dgp谢谢你,但我已经找到了那个帖子。我也寻找了很长时间的解决方案,并开始认为这是与Android 12有关的手机特定错误(我有一台带有Android 11和Android 12的像素3和像素6)。 - Lukas Fink
显示剩余3条评论
3个回答

14

我找到了解决方案。与官方文档中的声明相反,您仍然需要在清单中设置android.permission.ACCESS_FINE_LOCATIONandroid.permission.ACCESS_COARSE_LOCATION权限,并从移动用户请求这些权限。现在一切正常工作。


2
我让其他人测试过,甚至在一台安装了Android 12的新款三星手机上,仅通过蓝牙权限无法找到BLE设备。 BLE扫描器应用程序也会查询这些设备。 - Lukas Fink
对我来说,在Android 12(三星S10)上的BLE扫描器可以找到一些设备,但会过滤其他设备,即使已经授予了位置权限。目前还没有解决这个问题。 - Alektas
1
从官方文档来看,这可能会有所帮助。 如果您在android:usesPermissionFlags中包含neverForLocation,则会从扫描结果中过滤掉一些BLE信标。 - Mieszko Koźma
所以安卓文档是错的...仅在清单中声明是否足够,还是需要在运行时请求? - AndreaGobs
即使已经授予了精细定位权限,您仍然需要授予粗略定位权限。这很傻。谢谢,您的解决方案有效。 - Sadique Khan
显示剩余2条评论

11

我发现安卓12仍需要启用定位服务,android.permission.ACCESS_FINE_LOCATION以及额外的android.permission.BLUETOOTH_SCAN权限,没有android:usesPermissionFlags="neverForLocation"标志在AndroidManifest中,并且用户在运行时显式授予这些权限来搜索信标设备。

如果在AndroidManifest中将android.permission.BLUETOOTH_SCAN权限的android:usesPermissionFlags="neverForLocation"标志添加到中,就可以找到其他设备类型而无需启用定位服务和ACCESS_FINE_LOCATION权限。


2
是的,信标仍然需要ACCESS_FINE_LOCATION权限,因为信标会_揭示位置_。实质上,neverForLocation属性表示:“我只使用它来连接没有任何已知特定位置的设备。”尽管这并没有得到很好的记录,但这就是我的理解。 - Steven Jeuris

0
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
android:name="android.permission.BLUETOOTH_CONNECT"

将这两个权限添加到清单中,并请求用户授权


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接