From e09a25a24e7f834c91d383e27b4546b0cda42fe8 Mon Sep 17 00:00:00 2001 From: Alex Blasche <alexander.blasche@qt.io> Date: Wed, 14 Sep 2016 12:12:09 +0200 Subject: [PATCH] Add capability to ask for Location permission at runtime This is required since Android v23+. Task-number: QTBUG-55988 Change-Id: I41777cfbb6fde38dc0f8045c9320f420bb0b43a2 Reviewed-by: BogDan Vatra <bogdan@kdab.com> --- .../position/android/src/jnipositioning.cpp | 29 +++++++++++++++++++ src/plugins/position/android/src/src.pro | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp index e0124eb6b..547d0fadf 100644 --- a/src/plugins/position/android/src/jnipositioning.cpp +++ b/src/plugins/position/android/src/jnipositioning.cpp @@ -41,6 +41,7 @@ #include <QDebug> #include <QMap> #include <QtGlobal> +#include <QtCore/private/qjnihelpers_p.h> #include <android/log.h> #include <jni.h> #include <QGeoPositionInfo> @@ -367,6 +368,20 @@ namespace AndroidPositioning { QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); if (source) { + // Android v23+ requires runtime permission check and requests + QString permission(QLatin1String("android.permission.ACCESS_FINE_LOCATION")); + + if (QtAndroidPrivate::checkPermission(permission) == QtAndroidPrivate::PermissionsResult::Denied) { + const QHash<QString, QtAndroidPrivate::PermissionsResult> results = + QtAndroidPrivate::requestPermissionsSync(env.jniEnv, QStringList() << permission); + if (!results.contains(permission) + || results[permission] == QtAndroidPrivate::PermissionsResult::Denied) + { + qWarning() << "Position retrieval not possible due to missing permission (ACCESS_FINE_LOCATION)"; + return QGeoPositionInfoSource::AccessError; + } + } + int errorCode = env.jniEnv->CallStaticIntMethod(positioningClass, startUpdatesMethodId, androidClassKey, positioningMethodToInt(source->preferredPositioningMethods()), @@ -404,6 +419,20 @@ namespace AndroidPositioning { QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); if (source) { + // Android v23+ requires runtime permission check and requests + QString permission(QLatin1String("android.permission.ACCESS_FINE_LOCATION")); + + if (QtAndroidPrivate::checkPermission(permission) == QtAndroidPrivate::PermissionsResult::Denied) { + const QHash<QString, QtAndroidPrivate::PermissionsResult> results = + QtAndroidPrivate::requestPermissionsSync(env.jniEnv, QStringList() << permission); + if (!results.contains(permission) + || results[permission] == QtAndroidPrivate::PermissionsResult::Denied) + { + qWarning() << "Position update not possible due to missing permission (ACCESS_FINE_LOCATION)"; + return QGeoPositionInfoSource::AccessError; + } + } + int errorCode = env.jniEnv->CallStaticIntMethod(positioningClass, requestUpdateMethodId, androidClassKey, positioningMethodToInt(source->preferredPositioningMethods())); diff --git a/src/plugins/position/android/src/src.pro b/src/plugins/position/android/src/src.pro index 3a19c85e7..36facc55b 100644 --- a/src/plugins/position/android/src/src.pro +++ b/src/plugins/position/android/src/src.pro @@ -1,6 +1,6 @@ TARGET = qtposition_android -QT = core positioning +QT = core core-private positioning HEADERS = \ positionfactory_android.h \ -- GitLab