diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2020-02-12 14:57:41 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2020-02-26 10:35:11 +0100 |
commit | b4bd5c9852c1414cc45a551590fa485ade764c63 (patch) | |
tree | 8cce67a0b7e2f559468d0547fef3abe9645c76f9 | |
parent | e851596c284bfa3ef5be1bb982cf8a57360baed9 (diff) | |
download | qtconnectivity-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.cpp | 38 |
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 |