Android 12 更新后,特定设备上出现“缺少权限 android.permission.BLUETOOTH”

Alk*_*aaf 20 android bluetooth android-permissions flutter android-12

所以我有一个连接到蓝牙打印机的应用程序。它很好并且可以在除以下设备之外的所有设备上运行:

  • 小米红米 Note 10 Pro(已更新至 Android 12,MIUI 13.0.1)
  • Oppo Reno 5 4G(型号:CPH2159)(已更新至 android 12,带有 Color Os 13)

关于Google开发者,android 12使用这三个权限

android.permission.BLUETOOTH_CONNECT
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH_ADVERTISE
Run Code Online (Sandbox Code Playgroud)

但是当我尝试连接打印机时,我收到了这个错误,这让我抓狂。

2022-03-21 09:23:49.039 29022-29206/com.xxxx.xxxxx E/BThermalPrinterPlugin: UID 10324 / PID 29022 lacks permission android.permission.BLUETOOTH
    java.lang.SecurityException: UID 10324 / PID 29022 lacks permission android.permission.BLUETOOTH
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2425)
        at android.os.Parcel.createException(Parcel.java:2409)
        at android.os.Parcel.readException(Parcel.java:2392)
        at android.os.Parcel.readException(Parcel.java:2334)
        at android.bluetooth.IBluetoothSocketManager$Stub$Proxy.connectSocket(IBluetoothSocketManager.java:227)
        at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:404)
        at id.kakzaki.blue_thermal_printer.BlueThermalPrinterPlugin.lambda$connect$1$id-kakzaki-blue_thermal_printer-BlueThermalPrinterPlugin(BlueThermalPrinterPlugin.java:544)
        at id.kakzaki.blue_thermal_printer.BlueThermalPrinterPlugin$$ExternalSyntheticLambda1.run(Unknown Source:6)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:920)
Run Code Online (Sandbox Code Playgroud)

是这种 ROM/平台/设备特定的问题。android.permission.BLUETOOTH 应该在 android 11 及更低版本上使用,因为 android 12 及更高版本将其替换为 android.permission.BLUETOOTH_CONNECT,对吗?那么为什么我首先会遇到这些特定的设备错误呢?

我已经在三星 A52 和 Android 12 上尝试过,没有任何问题。

我已在清单上添加了必要的权限

AndroidManifest.xml

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
Run Code Online (Sandbox Code Playgroud)

和运行时权限请求


        var perm = arrayListOf(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN
        )
        //permission
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { //  >= android 12
                perm.add(Manifest.permission.BLUETOOTH_CONNECT)
                perm.add(Manifest.permission.BLUETOOTH_SCAN)
                perm.add(Manifest.permission.BLUETOOTH_ADVERTISE)
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(
                    perm.toTypedArray(), ActivityBase.REQ_PERM
                )
            }

Run Code Online (Sandbox Code Playgroud)

小智 17

正如您已经发现的,小米似乎对蓝牙规范的实现不正确。

我遇到了和你一样的问题,并在 AndroidManifest.xml 中声明android.permission.BLUETOOTH解决了这个问题,即使对于 Android 12 也是如此。

因此,不要添加文档建议的以下行:

<uses-permission android:name="android.permission.BLUETOOTH"
             android:maxSdkVersion="30" />
Run Code Online (Sandbox Code Playgroud)

我补充道:

<uses-permission android:name="android.permission.BLUETOOTH" tools:remove="android:maxSdkVersion" />
Run Code Online (Sandbox Code Playgroud)

我必须添加tools:remove属性,因为我使用的蓝牙库已经添加了 maxSdkVersion 属性。因此,即使我自己没有添加它,它也会包含在我的合并清单中。

另请注意,在清单中添加此权限不会在三星等其他 Android 12 设备上导致任何进一步的问题或权限提示。