安卓 12 更新后在特定设备上获得"lacks permission android.permission.BLUETOOTH"



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

  • 小米红米note 10 Pro(更新至安卓12,MIUI 13.0.1(
  • Oppo Reno 5 4G(型号:CPH2159((更新至android 12,颜色为Os 13(

关于谷歌开发者,安卓12使用这三个权限

android.permission.BLUETOOTH_CONNECT
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH_ADVERTISE

但当我尝试连接打印机时,我遇到了一个错误,导致我拔出了头发。

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)

是这种ROM/平台/设备特定的问题。android.permission.BLUETOOTH应该在android 11及以下版本上使用,因为android 12及以上版本将其替换为android.pPermission.BLUET OOTH_CONNECT,对吧?那么,为什么我一开始就出现了这些特定的设备错误呢?

我试过用安卓12在三星A52,没有任何问题。

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

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" />

和运行时许可请求


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
)
}

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

我遇到了和你一样的问题,并在AndroidManifest.xml中声明android.permission.BLUETOOTH解决了这个问题,甚至适用于android 12。

因此,没有添加文档中建议的以下行:

<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />

我补充道:

<uses-permission android:name="android.permission.BLUETOOTH" tools:remove="android:maxSdkVersion" />

我不得不添加工具:删除属性,因为我使用的蓝牙库已经添加了maxSdkVersion属性。所以它被包含在我的合并清单中,即使我自己没有添加它。

还要注意,在清单中添加此权限不会在三星等其他安卓12设备上造成任何进一步的问题或权限提示。

我认为这是小米/MUI的问题。要使其工作,可以与android:targetSdkVersion="30"一起使用,而不能与android:targetSdkVersion="31"一起使用。

以下代码片段演示了如果应用程序针对Android 12或更高版本,如何在应用程序中声明蓝牙相关权限:

<manifest>
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can strongly assert that your app
doesn't derive physical location. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...

您可以在这里查看更多详细信息。

最新更新