10

I'm trying to upgrade a Bluetooth Low Energy app (connects to a custom physical device) to Android 12. I've set up everything as in the documentation, but it doesn't work.

Permissions:

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

Code:

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

I also ask for the permissions using the ActivityResultContracts.RequestMultiplePermissions() contract. When I read through the logs I can see, that the permissions are set.

Now when I call the start()-Method, I never get the onScanResult(...)-Method called. When I switch to a device with Android 11 on it, it works without any problems. When I start the BLE Scanner app (from play store), it finds the device.

UPDATE: When I set back the targetSdk to 30, everything works well (with old permissions, etc. for sure).

Does anyone have the same problem or even fixed it? Would be grateful for any advices.

Thanks!

Lukas Fink
  • 627
  • 6
  • 18
  • `BLUETOOTH_ADVERTISE`, `BLUETOOTH_CONNECT`, and `BLUETOOTH_SCAN` are runtime permissions, therefore the app explicitly must request user approval. I can't see this in your snippet. For more Information: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions – Risto Jan 04 '22 at 12:34
  • @Risto Thanks for explaining this. But I already do that. I'll update my post. – Lukas Fink Jan 04 '22 at 13:06
  • I assume your target sdk is 31 (Android 12)? – Michael Kotzjan Jan 04 '22 at 14:00
  • 1
    Hi @MichaelKotzjan my Target SDK was 31, I changed it for testing purposes to 32 – Lukas Fink Jan 04 '22 at 14:04
  • Maybe you can find some answers on this thread : https://stackoverflow.com/questions/67722950/android-12-new-bluetooth-permissions – dgp Jan 06 '22 at 15:59
  • Hey @dgp thank you but I already found that thread. I'm also searching a long time for a solution and begin to think this is a phone-specific bug with Android 12 (have a pixel 3 and a pixel 6 both with Android 11 and Android 12). – Lukas Fink Jan 06 '22 at 19:56
  • @LukasWerner the accepted answer of this thread mention a bug with Android 12 beta. Maybe this bug is not fully fixed on pixels ? – dgp Jan 07 '22 at 08:04
  • @dgp yes I know but Android 12 isn't in beta anymore and the thread also says that it's fixed already. Additionally, what I wonder about is that the ble scanner app works – Lukas Fink Jan 07 '22 at 13:14

3 Answers3

14

I found the solution. Contrary to the statements in the official documentation you still need the android.permission.ACCESS_FINE_LOCATION and android.permission.ACCESS_COARSE_LOCATION permissions to be set in the Manifest and request them from the mobile user. Now everything works fine again.

Lukas Fink
  • 627
  • 6
  • 18
  • That was strange. I certainly do not need that on my Pixel 3 with Android 12. – Emil Jan 11 '22 at 08:14
  • 2
    I had others test that and even on a newer Samsung with android 12 ble devices could not be found with the Bluetooth permissions only. The BLE Scanner App queries those as well – Lukas Fink Jan 11 '22 at 14:24
  • For me, the BLE scanner on Android 12 (Samsung S10) finds some devices but filters others, even with location permissions. Haven't resolved this issue yet. – Alektas Jan 20 '22 at 08:46
  • 1
    @Alektas From official documentation, this might be helpful. "If you include neverForLocation in your android:usesPermissionFlags, some BLE beacons are filtered from the scan results." – Mieszko Koźma Feb 03 '22 at 09:48
  • So Android documentation is wrong... Is it sufficient to declare them into the manifest or also to ask them runtime? – AndreaGobs Feb 24 '22 at 11:15
  • That's also what I experienced on my Zenfone 8. Possibly this is manufacturer related? – Steven Jeuris Jul 07 '22 at 19:07
  • even after giving fine location permission you have to give coarse location. that is silly. thanks your solution works – Sadique Khan Nov 23 '22 at 15:27
10

I found that Andriod 12 still requires Location services enabled, android.permission.ACCESS_FINE_LOCATION and additionally android.permission.BLUETOOTH_SCAN without android:usesPermissionFlags="neverForLocation" flag in AndroidManifest, and explicit granting of these permissions by user in runtime to search for beacon devices.

Other device types can be found without Location services and ACCESS_FINE_LOCATION if in AndroidManifest you add the flag android:usesPermissionFlags="neverForLocation" to android.permission.BLUETOOTH_SCAN permission.

Alektas
  • 556
  • 4
  • 11
  • 1
    Yes, **beacons** still need `ACCESS_FINE_LOCATION`. Since beacons _reveal location_. The `neverForLocation` attribute in essence says: "I'm only using this to connect to devices that don't have any known specific location." Granted, that's not well-documented, but that's how I understood it. – Steven Jeuris Jul 07 '22 at 19:50
0
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
android:name="android.permission.BLUETOOTH_CONNECT"

Add these two permission in manifest and make to ask permission from user

General Grievance
  • 4,555
  • 31
  • 31
  • 45