From 54666d4b42cc212ad1639a058e90ad1f17eed898 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Tue, 20 Mar 2018 17:08:50 +0100 Subject: Ensure that BTLE scan works if app has ACCESS_FINE_LOCATION BTLE scanning requires Android's ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION. The permission must be requested at runtime (assuming it was declared in the manifest file). So far, Qt only ever requested coarse location although FINE location is a perfectly OK substitute and the manifest may only declare FINE location. Task-number: QTBUG-66490 Change-Id: I4ce6a25735cb7cdf939f94f8fa545676d391ca2d Reviewed-by: Christian Stromme --- .../qbluetoothdevicediscoveryagent_android.cpp | 30 ++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp index 303dd67f..c7afd578 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp @@ -147,23 +147,33 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent } // check Android v23+ permissions - // -> BTLE search requires android.permission.ACCESS_COARSE_LOCATION + // -> BTLE search requires android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION if (requestedMethods & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod && QtAndroid::androidSdkVersion() >= 23) { - QString permission(QLatin1String("android.permission.ACCESS_COARSE_LOCATION")); + const QString coarsePermission(QLatin1String("android.permission.ACCESS_COARSE_LOCATION")); + const QString finePermission(QLatin1String("android.permission.ACCESS_FINE_LOCATION")); // do we have required permission already, if so nothing to do - if (QtAndroidPrivate::checkPermission(permission) == QtAndroidPrivate::PermissionsResult::Denied) { - qCWarning(QT_BT_ANDROID) << "Requesting ACCESS_COARSE_LOCATION permission"; + if (QtAndroidPrivate::checkPermission(coarsePermission) == QtAndroidPrivate::PermissionsResult::Denied + && QtAndroidPrivate::checkPermission(finePermission) == QtAndroidPrivate::PermissionsResult::Denied) { + qCWarning(QT_BT_ANDROID) << "Requesting ACCESS_*_LOCATION permission"; QAndroidJniEnvironment env; const QHash results = - QtAndroidPrivate::requestPermissionsSync(env, QStringList() << permission); - if (!results.contains(permission) - || results[permission] == QtAndroidPrivate::PermissionsResult::Denied) - { - qCWarning(QT_BT_ANDROID) << "Search not possible due to missing permission (ACCESS_COARSE_LOCATION)"; + QtAndroidPrivate::requestPermissionsSync(env, QStringList() << coarsePermission << finePermission); + + bool permissionReceived = false; + for (const QString &permission: results.keys()) { + qCDebug(QT_BT_ANDROID) << permission << (results[permission] == QtAndroidPrivate::PermissionsResult::Denied); + if ((permission == coarsePermission || permission == finePermission) + && results[permission] == QtAndroidPrivate::PermissionsResult::Granted) { + permissionReceived = true; + break; + } + } + if (!permissionReceived) { + qCWarning(QT_BT_ANDROID) << "Search not possible due to missing permission (ACCESS_COARSE|FINE_LOCATION)"; lastError = QBluetoothDeviceDiscoveryAgent::UnknownError; errorString = QBluetoothDeviceDiscoveryAgent::tr("Missing Location permission. Search is not possible."); emit q->error(lastError); @@ -171,7 +181,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent } } - qCWarning(QT_BT_ANDROID) << "ACCESS_COARSE_LOCATION permission available"; + qCWarning(QT_BT_ANDROID) << "ACCESS_COARSE|FINE_LOCATION permission available"; } // install Java BroadcastReceiver -- cgit v1.2.3