Fix some permission backwards compatibility issues with older android versions

This commit is contained in:
Michael Zanetti 2022-12-15 14:03:12 +01:00
parent 8c18d73a63
commit 3fca15c7ee
2 changed files with 54 additions and 22 deletions

View File

@ -5,25 +5,14 @@
#include <QAndroidIntent> #include <QAndroidIntent>
#include <QOperatingSystemVersion> #include <QOperatingSystemVersion>
#include "logging.h"
NYMEA_LOGGING_CATEGORY(dcPlatformPermissions, "PlatformPermissions")
PlatformPermissionsAndroid * PlatformPermissionsAndroid::s_instance = nullptr; PlatformPermissionsAndroid * PlatformPermissionsAndroid::s_instance = nullptr;
#define FLAG_ACTIVITY_NEW_TASK 0x10000000 #define FLAG_ACTIVITY_NEW_TASK 0x10000000
QHash<PlatformPermissions::Permission, QStringList> permissionMapV31 = {
// TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough.
{PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}},
{PlatformPermissions::PermissionNotifications, {"android.permission.POST_NOTIFICATIONS"}},
};
QHash<PlatformPermissions::Permission, QStringList> permissionMapV30 = {
{PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}},
{PlatformPermissions::PermissionNotifications, {"android.permission.POST_NOTIFICATIONS"}},
};
PlatformPermissionsAndroid::PlatformPermissionsAndroid(QObject *parent) PlatformPermissionsAndroid::PlatformPermissionsAndroid(QObject *parent)
: PlatformPermissions{parent} : PlatformPermissions{parent}
{ {
@ -44,12 +33,14 @@ PlatformPermissionsAndroid::PlatformPermissionsAndroid(QObject *parent)
void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permission permission) void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permission permission)
{ {
if (permissionMap().contains(permission)) { if (permissionMap().contains(permission)) {
qCDebug(dcPlatformPermissions()) << "Requesting permissions:" << permissionMap().value(permission);
QtAndroid::requestPermissions({permissionMap().value(permission)}, &permissionResultCallback); QtAndroid::requestPermissions({permissionMap().value(permission)}, &permissionResultCallback);
} }
} }
void PlatformPermissionsAndroid::openPermissionSettings() void PlatformPermissionsAndroid::openPermissionSettings()
{ {
qCDebug(dcPlatformPermissions()) << "Opening permission dialog.";
QAndroidJniObject packageName = QtAndroid::androidContext().callObjectMethod("getPackageName", "()Ljava/lang/String;"); QAndroidJniObject packageName = QtAndroid::androidContext().callObjectMethod("getPackageName", "()Ljava/lang/String;");
QString packageUri = "package:" + packageName.toString(); QString packageUri = "package:" + packageName.toString();
QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", QAndroidJniObject::fromString(packageUri).object()); QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", QAndroidJniObject::fromString(packageUri).object());
@ -62,29 +53,68 @@ void PlatformPermissionsAndroid::openPermissionSettings()
QHash<PlatformPermissions::Permission, QStringList> PlatformPermissionsAndroid::permissionMap() const QHash<PlatformPermissions::Permission, QStringList> PlatformPermissionsAndroid::permissionMap() const
{ {
QOperatingSystemVersion osVersion = QOperatingSystemVersion::current(); QOperatingSystemVersion osVersion = QOperatingSystemVersion::current();
if (osVersion.majorVersion() <= 11) { if (osVersion.majorVersion() <= 9) {
return permissionMapV30; return {
{PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION"}}
};
} }
return permissionMapV31; if (osVersion.majorVersion() <= 10) {
return {
{PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}}
};
}
if (osVersion.majorVersion() <= 12) {
return {
// TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough.
{PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}}
};
}
return {
// TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough.
{PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}},
{PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}},
{PlatformPermissions::PermissionNotifications, {"android.permission.POST_NOTIFICATIONS"}}
};
} }
PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermission(Permission permission) const PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermission(Permission permission) const
{ {
PermissionStatus status = PermissionStatusGranted; PermissionStatus status = PermissionStatusGranted;
QStringList androidPermissions = permissionMap().value(permission); QStringList androidPermissions = permissionMap().value(permission);
qCDebug(dcPlatformPermissions()) << "Checking permission" << permission << "(" << androidPermissions << ")";
foreach (const QString androidPermission, androidPermissions) { foreach (const QString androidPermission, androidPermissions) {
if (QtAndroid::shouldShowRequestPermissionRationale(androidPermission)) { if (QtAndroid::shouldShowRequestPermissionRationale(androidPermission) || m_requestedButDeniedPermissions.contains(androidPermission)) {
return PermissionStatusDenied; qCDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "denied";
status = PermissionStatusDenied;
} }
if (QtAndroid::checkPermission(androidPermission) == QtAndroid::PermissionResult::Denied) { if (QtAndroid::checkPermission(androidPermission) == QtAndroid::PermissionResult::Denied) {
status = PermissionStatusNotDetermined; qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "not determined";
if (status != PermissionStatusDenied) {
status = PermissionStatusNotDetermined;
}
} else {
qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "granted";
} }
} }
qCDebug(dcPlatformPermissions()) << "Permission status for:" << permission << ":" << status;
return status; return status;
} }
void PlatformPermissionsAndroid::permissionResultCallback(const QtAndroid::PermissionResultMap &/*results*/) void PlatformPermissionsAndroid::permissionResultCallback(const QtAndroid::PermissionResultMap &results)
{ {
foreach (const QString &androidPermission, results.keys()) {
qCDebug(dcPlatformPermissions()) << "Permission result callback:" << androidPermission << (results.value(androidPermission) == QtAndroid::PermissionResult::Granted ? "Granted" : "Denied");
if (results.value(androidPermission) == QtAndroid::PermissionResult::Denied) {
s_instance->m_requestedButDeniedPermissions.append(androidPermission);
}
}
emit s_instance->bluetoothPermissionChanged(); emit s_instance->bluetoothPermissionChanged();
emit s_instance->locationPermissionChanged(); emit s_instance->locationPermissionChanged();
emit s_instance->backgroundLocationPermissionChanged(); emit s_instance->backgroundLocationPermissionChanged();

View File

@ -21,6 +21,8 @@ signals:
private: private:
QHash<PlatformPermissions::Permission, QStringList> permissionMap() const; QHash<PlatformPermissions::Permission, QStringList> permissionMap() const;
QStringList m_requestedButDeniedPermissions;
static PlatformPermissionsAndroid *s_instance; static PlatformPermissionsAndroid *s_instance;
static void permissionResultCallback(const QtAndroid::PermissionResultMap &results); static void permissionResultCallback(const QtAndroid::PermissionResultMap &results);