Reputation: 325
So i have an application that connect to bluetooth printer. It is fine and running on all devices except these devices:
Regarding Google developer, android 12 using these three permission
android.permission.BLUETOOTH_CONNECT
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH_ADVERTISE
but when i tried to connect on my printer, i got this error that makes me pulls my hair out.
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)
is this sort of ROM/platform/device specific problem. android.permission.BLUETOOTH supposed to be used on android 11 and below because android 12 and above replaces it with android.permission.BLUETOOTH_CONNECT, right? then why i got those specific device errors in the first place?
i have tried in Samsung A52 with android 12 and got no problem at all.
i have added necessary permission on manifest
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" />
and runtime permission request
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
)
}
Upvotes: 22
Views: 20083
Reputation: 457
As you already found, Xiaomi seems to have an incorrect implementation of the Bluetooth spec.
I had the same problem as you do and solved it declaring android.permission.BLUETOOTH in AndroidManifest.xml, even for Android 12.
So, instead of adding the following line, which the documentation suggests:
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
I added:
<uses-permission android:name="android.permission.BLUETOOTH" tools:remove="android:maxSdkVersion" />
I had to add the tools:remove attribute because the Bluetooth library I was using was adding the maxSdkVersion attribute already. So it was being included in my merged manifest even if I didn't add it myself.
Also note that adding this permission in the manifest didn't cause any further problems or permission prompts on other Android 12 devices like Samsung.
Upvotes: 20
Reputation: 19
I think it is a Xiaomi/MIUI issues. To make it work, you can use with android:targetSdkVersion="30"
and not with android:targetSdkVersion="31"
.
Upvotes: 1
Reputation: 964
The following code snippet demonstrates how to declare Bluetooth-related permissions in your app if it targets Android 12 or higher:
<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" />
...
you can check more details here source.
Upvotes: -3