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
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 :)
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()
checkSelfPermission
instead of isLocationEnabled
? –
Lathrope 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);
Manifest.permission.READ_EXTERNAL_STORAGE
? I didn't need that one... –
Manning 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.
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
}
};
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.
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.
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)
© 2022 - 2024 — McMap. All rights reserved.