Android 10 not working with BLE Bluetooth scanning
Asked Answered
M

9

24

I am working on BLE Bluetooth scanning is working on all devices except the Android 10. Android 10 is not working, anyone please answer the question for the version 10 issues for scanning BLE Bluetooth

Melissiamelita answered 17/10, 2019 at 9:0 Comment(8)
You don't provide any information in what way it fails. But if you target Android 10 then you need ACCESS_FINE_LOCATION to scan BLE. ACCESS_COARSE_LOCATION doesn't work anymore in Android 10.Sexlimited
yes, i implemented all permission , the device is scan and get a address, but it could not connect ,IBluetoothGatt class is can not resolve is not work on connecting the device, in api 29 is only not workingMelissiamelita
Then you should change your question since you say scanning woks but it is connect that fails. Include your code and the error messages.Sexlimited
currently i get this errorD/BluetoothGatt: onClientConnectionState() - status=133 clientIf=8 device=88:BF:E4:95:55:51 D/BluetoothGatt: refresh() - device: 88:BF:E4:95:55:51 D/BluetoothGatt: close() D/BluetoothGatt: unregisterApp() - mClientIf=8 D/BluetoothGatt: connect() - device: 88:BF:E4:95:55:51, auto: false D/BluetoothGatt: registerApp() D/BluetoothGatt: registerApp() - UUID=af64bcfc-a9dc-40a9-994a-71b2ac16d5e0 D/BluetoothGatt: onClientRegistered() - status=0 clientIf=8Melissiamelita
Android 10 is not working on BLE Bluetooth connection tittle i post the codeMelissiamelita
Could you check the HCI log? If you go to developer settings in the phone, enable HCI snoop log, restart the phone, reproduce the problem and then press "take bug report" in developer settings. Send the file to yourself and extract the log from FS/data/misc/bluetooth/logs and open it in Wireshark. If Android host BLE stack behaves correctly you should see that it attempts to connect but the remote device never responds.Sexlimited
I found out that it's important to have ACCESS_FINE_LOCATION defined in your Manifest too.Susan
You need runtime permission for "Location permission" in your app. See: developer.android.com/training/location/…Lathrope
M
27

To make BLE scanning work on Android apps targeting Android 10 you need to ask the user for

ACCESS_BACKGROUND_LOCATION

along with ACCESS_FINE_LOCATION and also don't forget to add the permission in the manifest:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Here's the explanation why:

Android 10 (API level 29) introduces a number of features and behavior changes to better protect users' privacy. These changes extend the transparency and control that users have over their data and the capabilities they give to apps.

Your problem in short:

Access to device location in the background requires permission

To support the additional control that users have over an app's access to location information, Android 10 introduces the ACCESS_BACKGROUND_LOCATION permission.

Unlike the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions, the ACCESS_BACKGROUND_LOCATION permission only affects an app's access to location when it runs in the background. An app is considered to be accessing location in the background unless one of the following conditions is satisfied:

An activity belonging to the app is visible. The app is running a foreground service that has declared a foreground service type of location.

To declare the foreground service type for a service in your app, set your app's targetSdkVersion or compileSdkVersion to 29 or higher. Learn more about how foreground services can continue user-initiated actions that require access to location.

Hope this fixes your problem :)

Managing answered 2/11, 2019 at 8:48 Comment(3)
Hi, do you know if using "connected_device" instead of "location" in a foreground service would be enough for BLE connections? The documentation hints at Bluetooth connection but there's not much information about it: developer.android.com/reference/android/content/pm/…Islas
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> would work just fine.Lathrope
@Lathrope I already had ACCESS_FINE_LOCATION in my AndroidManifest and also asked the user for the same permission, but not worked for me.Sectarian
H
16

You need to have location enabled to perform a BLE scan on android 10. To check if location is enabled and ask user to enable location service (Kotlin):

val lm = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (!LocationManagerCompat.isLocationEnabled(lm)) {
    // Start Location Settings Activity, you should explain to the user why he need to enable location before.
    startActivity(Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS))
}

LocationManagerCompat class is available in androidx.appcompat:appcompat:1.1.0 dependency, if you don't use androidx, you can use instead :

lm.isLocationEnabled()
Handset answered 21/2, 2020 at 9:1 Comment(1)
Can we use checkSelfPermission instead of isLocationEnabled?Lathrope
S
14

Adding the following permissions to AndroidManifest.xml is not enough

android.permission.ACCESS_FINE_LOCATION,  
android.permission.ACCESS_COARSE_LOCATION,  
android.permission.ACCESS_BACKGROUND_LOCATION. 

Add permissions to MainActivity such as

ActivityCompat.requestPermissions(
  this, 
  new String[] 
    {
      Manifest.permission.ACCESS_FINE_LOCATION, 
      Manifest.permission.ACCESS_COARSE_LOCATION, 
      Manifest.permission.ACCESS_BACKGROUND_LOCATION, 
      Manifest.permission.READ_EXTERNAL_STORAGE
  }, 0);
Superstar answered 12/11, 2020 at 22:27 Comment(3)
This is the only correct reply, I had to do this for BLE to workCagle
Note it should be String[]. My app stopped finding BLE devices a few weeks ago even though it has been working for years. I tried several combinations of permissions. This is the only thing that fixed it. I did change to ACCESS_FINE_LOCATION from ACCESS_COARSE_LOCATION in addition because the docs say that is required. You don't need both, and I did not need READ_EXTERNAL_STORAGE or ACCESS_BACKGROUND_LOCATION for my app. (They are making it harder and harder to use ACCESS_BACKGROUND_LOCATION. You don't need it if you are only scanning when the app is visible.) Thanks.Splenic
Manifest.permission.READ_EXTERNAL_STORAGE? I didn't need that one...Manning
L
3

I faced the same problem, and I have just fixed it using cordova-plugin-android-permissions.

Android 10 (SDK 29) requires ACCESS_FINE_LOCATION, while previous versions require only ACCESS_COARSE_LOCATION. (more info in this Android Developers page)

Unlike some other answers state, the ACCESS_BACKGROUD_LOCATION is not required. It's better not to require it unless you really need it. Play Store considers background location a dangerous permission, and will ask you to fill in some forms to justify why do you need it.

Old plugins would ask only ACCESS_COARSE_LOCATION permission, which was enough for Android 9 (SDK 28) and older versions. The best solution is to update the plugin. But if it is hard to do, there is an easy workaround.

Add cordova-plugin-android-permissions (npm link) to your project, and use it to ask ACCESS_FINE_LOCATION permission.

Add this code to your "device ready" function to check if your app already has this permission or not:

permissions = cordova.plugins.permissions;
permissions.checkPermission(permissions.ACCESS_FINE_LOCATION, checkPermissionSuccessCallback, checkPermissionErrorCallback);

And then create the following callback function to ask user permission:

function checkPermissionSuccessCallback(status) {
    if (status.hasPermission) {
        console.log("Permission OK");
    } else {
        console.log("Permission not OK");
        // ask user permission
        permissions.requestPermission(permissions.ACCESS_FINE_LOCATION, requestPermissionSuccessCallback, requestPermissionErrorCallback);
    }
}

You don't need to add anything to your "config.xml" to get this permission.

Legofmutton answered 29/11, 2020 at 22:30 Comment(0)
R
2

try this

//gradle
dependencies {
implementation 'no.nordicsemi.android.support.v18:scanner:1.4.3'
}
//import
import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;
import no.nordicsemi.android.support.v18.scanner.ScanCallback;
import no.nordicsemi.android.support.v18.scanner.ScanResult;
import no.nordicsemi.android.support.v18.scanner.ScanSettings;
//init scan setting
final ScanSettings settings = new ScanSettings.Builder().setReportDelay(1000).setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
//start scan
scanner.startScan(null, settings, scanCallback);
//scan callback
private final ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(final int callbackType, @NonNull final ScanResult result) {
            super.onScanResult(callbackType, result);
        }
        public void onBatchScanResults(@NonNull final List<ScanResult> results) {
            for (final ScanResult result : results) {
                //result.getDevice() is scanned device
            }
        }
        @Override
        public void onScanFailed(final int errorCode) {
            // should never be called
        }
    };
Rashida answered 12/11, 2020 at 7:37 Comment(0)
H
1

For me it is working if i use fine permission in AndroidManifest. Switch on the location in Settings of the phone manually, and set app permission to location.

Helices answered 9/7, 2020 at 18:17 Comment(0)
T
1

I suppose in android 10 having just the location permission is not enough. Your location service should be turned on while you are scanning for your device. So, ask the user for turning on the location service if it is turned off.

Alternative Solution: You can use Companion device pairing for android 8 and higher. Mind you, In my opinion, it is not well documented, and it might be a bit unstable. For example, when I assigned a scan filter (BLE Service UUID) the Companion device pairing crashed, but without that filter, it worked.

Thoughtless answered 16/12, 2020 at 8:40 Comment(0)
C
0

Try setting the callbackType to CALLBACK_TYPE_ALL_MATCHES, it solves the problem for me.

val scanSettings = ScanSettings.Builder()
scanSettings.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
scanSettings.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
scanSettings.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)

val filter = ScanFilter.Builder()
filter.setServiceUuid(ParcelUuid(Service_UUID))
bluetooth.bluetoothLeScanner.startScan(mutableListOf<ScanFilter>(filter.build()), scanSettings.build(), callback)
Cherey answered 22/3, 2021 at 19:44 Comment(0)
A
0

User need to allow "Location" - (GPS) on Device

enter image description here

Acanthous answered 16/9, 2021 at 9:12 Comment(2)
Hi Catherine, Your anwser need more details to be really usefull for other member.Deathful
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Cannabin

© 2022 - 2024 — McMap. All rights reserved.