THE PROBLEM
Hi, I have encountered a problem that I am not able to solve on my own. I am an intern at Haia Consultancy, and I develop using Kotlin for Android run platforms. I am unable to perform a BLE scan on the S21 android phone on Android 12, be it my code, or code from github. The application runs until I press the Scan button which performs a BLE Scan. The application crashes. This does not occur on lower versions of Android. It is very important that I am able to use android 12 targeted version in combination with Bluetooth Low Energy.
2022-12-07 16:01:45.692 28797-28797 AndroidRuntime
com...e.ultrawidebandproofofconcept E FATAL EXCEPTION: main
Process: com.example.ultrawidebandproofofconcept, PID: 28797
java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for AttributionSource { uid = 10366, packageName = com.example.ultrawidebandproofofconcept, attributionTag = null, token = android.os.BinderProxy@ff32c8f, next = null }: GattService registerScanner
at android.os.Parcel.createExceptionOrNull(Parcel.java:2438)
at android.os.Parcel.createException(Parcel.java:2422)
at android.os.Parcel.readException(Parcel.java:2405)
at android.os.Parcel.readException(Parcel.java:2347)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.registerScanner(IBluetoothGatt.java:1886)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.startRegistration(BluetoothLeScanner.java:519)
at android.bluetooth.le.BluetoothLeScanner.startScan(BluetoothLeScanner.java:305)
at android.bluetooth.le.BluetoothLeScanner.startScan(BluetoothLeScanner.java:161)
at com.example.ultrawidebandproofofconcept.MainActivity.startBleScan(MainActivity.kt:96)
at com.example.ultrawidebandproofofconcept.MainActivity.onCreate$lambda-0(MainActivity.kt:80)
at com.example.ultrawidebandproofofconcept.MainActivity.$r8$lambda$NQsLDkI5TsYB6INH-F0JwBK_SNM(Unknown Source:0)
at com.example.ultrawidebandproofofconcept.MainActivity$$ExternalSyntheticLambda2.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7792)
at android.widget.TextView.performClick(TextView.java:16112)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
at android.view.View.performClickInternal(View.java:7769)
at android.view.View.access$3800(View.java:910)
at android.view.View$PerformClick.run(View.java:30218)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8751)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Guide ive followed: https://punchthrough.com/android-ble-guide/
I have been following this guide until I came against the problem, at a certain point the webpage was updated notifying the reader that the guide is up to date with android 12 . I went to github repo of this guide and cloned the android12 branch (https://github.com/PunchThrough/ble-starter-android/tree/feature/android-12-up). The same error occurred as In my project which is mentioned above. Me and my colleagues suspect that something is wrong with either my laptop or the phone provided by the company. If targeted version is set to android 12 , the IDE suggests that you add an if statement to see if you the permissions are granted by the user: IDE's suggestion to see if the user has granted the permission if I do not add the if statement generated by the IDE, and try to perform a BLE scan after ive asked for the user permissions, the application still crashes. Ive tried to print out the results into the console to see if the permissions are really granted. I ask for the location permission from the user and I ask if the user is okay with me enabling the Bluetooth. printout permissions The results of the printout As you can see I get a -1 as return when I check if the permissions are given for the Bluetooth scan. I assume this is an error code since you should only be getting either true(1) or false(0).
ATTEMPTED SOLUTIONS
I have tried to request not only the fine location permission but also the coarse location permission from the user, as that is the main difference between android 12 and down when it comes to Bluetooth low energy. However this did not make the difference. Since I don’t use Bluetooth for location related purposes, I explicitly stated that I will not be using location in the manifest file. This did not work either. Does anyone know how to fix this? Can you run the projects referred in this document without the issues? Does anyone know the leads? Any bit of information helps!
SOFTWARE & HARDWARE SPECIFICATIONS
Run on s21 Android phone with Android 11
Project specifications:
targetSDK: 32
MinSDK: 31
Manifest permissions:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:remove="android:maxSdkVersion"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
The project Github Repository: https://github.com/FedorTselishchev/UWB-POC-Stackoverflow
Please help, I want to see my family again.
CodePudding user response:
It appears that Android 12 changes require your app to declare them in the manifest file:
If your app targets Android 12 (API level 31) or higher, declare the following permissions in your app's manifest file:
If your app looks for Bluetooth devices, such as BLE peripherals, declare the BLUETOOTH_SCAN permission.
Source: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions
CodePudding user response:
Since your targetSdk is 32 and minimumSdk 31, you may need to declare only
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
And request runtime user permissions as
requestMultiplePermissionLauncher.launch(arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT))
This will launch permission request for Nearby devices.
If you target lower SDK versions or intend to derive user locations, only then declare and request for location permissions.
Follow this link for learning how to request runtime permissions.
Edit: if you intend to only scan for ble devices, not connect, then declare and request only scan permission, vomit connect permission.