summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2020-02-12 14:57:41 +0100
committerAlex Blasche <alexander.blasche@qt.io>2020-02-26 10:35:11 +0100
commitb4bd5c9852c1414cc45a551590fa485ade764c63 (patch)
tree8cce67a0b7e2f559468d0547fef3abe9645c76f9
parente851596c284bfa3ef5be1bb982cf8a57360baed9 (diff)
downloadqtconnectivity-b4bd5c9852c1414cc45a551590fa485ade764c63.tar.gz
Add location-turned-on check before starting device discovery
The location permission and a running location service have been a prerequisite for a successful LE scan since Android v23. While the permission has always been checked before doing a bluetooth scan, the state of the location service was not checked. LE discovery without location turned on does not error out. It just reports zero discoveries. Starting with Android SDK v29, a classic Bluetooth discovery requires a running Location service too. Due to BluetoothAdapater.startDiscovery() returning an error code when location is turned off, it was time to check the location service before triggering the discovery to simplify the error handling for the API user. This patch ensures that location is turned on before any type of device discovery is started and the API reports an error reflecting this problem. Task-number: QTBUG-81875 Change-Id: Id51fd502ae24cbadbc704451fdf49d999224c16f Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> (cherry picked from commit fd48361a193889cdc25af8aeb311acc8ad85fa26)
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index ce3b8f10..07426f1f 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -185,6 +185,44 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
qCWarning(QT_BT_ANDROID) << "ACCESS_COARSE|FINE_LOCATION permission available";
}
+ // Double check Location service is turned on
+ bool locationTurnedOn = true; // backwards compatible behavior to previous Qt versions
+ const QAndroidJniObject locString = QAndroidJniObject::getStaticObjectField(
+ "android/content/Context", "LOCATION_SERVICE", "Ljava/lang/String;");
+ const QAndroidJniObject locService = QtAndroid::androidContext().callObjectMethod(
+ "getSystemService",
+ "(Ljava/lang/String;)Ljava/lang/Object;",
+ locString.object<jstring>());
+
+ if (locService.isValid()) {
+ if (QtAndroid::androidSdkVersion() >= 28) {
+ locationTurnedOn = bool(locService.callMethod<jboolean>("isLocationEnabled"));
+ } else {
+ // try GPS and network provider
+ QAndroidJniObject provider = QAndroidJniObject::getStaticObjectField(
+ "android/location/LocationManager", "GPS_PROVIDER", "Ljava/lang/String;");
+ bool gpsTurnedOn = bool(locService.callMethod<jboolean>("isProviderEnabled",
+ "(Ljava/lang/String;)Z", provider.object<jstring>()));
+
+ provider = QAndroidJniObject::getStaticObjectField(
+ "android/location/LocationManager", "NETWORK_PROVIDER", "Ljava/lang/String;");
+ bool providerTurnedOn = bool(locService.callMethod<jboolean>("isProviderEnabled",
+ "(Ljava/lang/String;)Z", provider.object<jstring>()));
+
+ locationTurnedOn = gpsTurnedOn || providerTurnedOn;
+ }
+ }
+
+ if (!locationTurnedOn) {
+ qCWarning(QT_BT_ANDROID) << "Search not possible due to turned off Location service";
+ lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
+ errorString = QBluetoothDeviceDiscoveryAgent::tr("Location service turned off. Search is not possible.");
+ emit q->error(lastError);
+ return;
+ }
+
+ qCDebug(QT_BT_ANDROID) << "Location turned on";
+
// install Java BroadcastReceiver
if (!receiver) {
// SDP based device discovery