Fix android permissions

This commit is contained in:
Simon Stürz 2025-12-04 21:46:40 +01:00
parent dec89523be
commit 590063aa19
2 changed files with 123 additions and 146 deletions

View File

@ -26,6 +26,8 @@
#include <QDebug>
#include <QApplication>
#include <QBluetoothPermission>
#include <QLocationPermission>
#include <QPermission>
#include <QOperatingSystemVersion>
#include <QFuture>
@ -64,15 +66,16 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio
case PlatformPermissions::PermissionBluetooth: {
QBluetoothPermission permission;
// Status prüfen
auto status = qApp->checkPermission(permission);
const auto permissionStatus = qApp->checkPermission(permission);
switch (status) {
switch (permissionStatus) {
case Qt::PermissionStatus::Granted:
qCDebug(dcPlatformPermissions()) << "Bluetooth permission already granted.";
status = PermissionStatusGranted;
break;
case Qt::PermissionStatus::Denied:
qCDebug(dcPlatformPermissions()) << "Bluetooth permission denied.";
status = PermissionStatusDenied;
break;
case Qt::PermissionStatus::Undetermined:
qCDebug(dcPlatformPermissions()) << "Bluetooth permission not yet requested. Requesting...";
@ -82,32 +85,75 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio
else
qCDebug(dcPlatformPermissions()) << "Bluetooth permission denied after request.";
});
status = PermissionStatusNotDetermined;
break;
}
break;
}
case PlatformPermissions::PermissionLocalNetwork: {
if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 13)) {
status = PermissionStatusGranted;
break;
}
const auto permissionResult = QtAndroidPrivate::checkPermission("android.permission.NEARBY_WIFI_DEVICES").result();
switch (permissionResult) {
case QtAndroidPrivate::Authorized:
qCDebug(dcPlatformPermissions()) << "Local network permission already granted.";
status = PermissionStatusGranted;
break;
case QtAndroidPrivate::Denied:
qCDebug(dcPlatformPermissions()) << "Local network permission denied.";
status = PermissionStatusDenied;
break;
case QtAndroidPrivate::Undetermined:
qCDebug(dcPlatformPermissions()) << "Local network permission not yet requested.";
status = PermissionStatusNotDetermined;
break;
}
break;
}
case PlatformPermissions::PermissionLocation: {
QLocationPermission permission;
permission.setAccuracy(QLocationPermission::Precise);
// Status prüfen
auto status = qApp->checkPermission(permission);
const auto permissionStatus = qApp->checkPermission(permission);
switch (status) {
switch (permissionStatus) {
case Qt::PermissionStatus::Granted:
qCDebug(dcPlatformPermissions()) << "Location permission already granted.";
status = PermissionStatusGranted;
break;
case Qt::PermissionStatus::Denied:
qCDebug(dcPlatformPermissions()) << "Location permission denied.";
status = PermissionStatusDenied;
break;
case Qt::PermissionStatus::Undetermined:
qCDebug(dcPlatformPermissions()) << "Location permission not yet requested. Requesting...";
qApp->requestPermission(permission, [](const QPermission &perm){
if (perm.status() == Qt::PermissionStatus::Granted)
qCDebug(dcPlatformPermissions()) << "Location permission granted after request.";
else
qCDebug(dcPlatformPermissions()) << "Location permission denied after request.";
});
qCDebug(dcPlatformPermissions()) << "Location permission not yet requested.";
status = PermissionStatusNotDetermined;
break;
}
break;
}
case PlatformPermissions::PermissionBackgroundLocation: {
if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 10)) {
// No dedicated background permission; use foreground status instead.
return checkPermission(PermissionLocation);
}
const auto permissionResult = QtAndroidPrivate::checkPermission("android.permission.ACCESS_BACKGROUND_LOCATION").result();
switch (permissionResult) {
case QtAndroidPrivate::Authorized:
qCDebug(dcPlatformPermissions()) << "Background location permission already granted.";
status = PermissionStatusGranted;
break;
case QtAndroidPrivate::Denied:
qCDebug(dcPlatformPermissions()) << "Background location permission denied.";
status = PermissionStatusDenied;
break;
case QtAndroidPrivate::Undetermined:
qCDebug(dcPlatformPermissions()) << "Background location permission not yet requested.";
status = PermissionStatusNotDetermined;
break;
}
break;
@ -148,7 +194,7 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi
switch (platformPermission) {
case PlatformPermissions::PermissionBluetooth:
qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission";
qApp->requestPermission(QLocationPermission{}, [platformPermission](const QPermission &permission) {
qApp->requestPermission(QBluetoothPermission{}, [platformPermission](const QPermission &permission) {
if (permission.status() == Qt::PermissionStatus::Denied) {
qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied.";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
@ -176,20 +222,49 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi
});
break;
}
case PlatformPermissions::PermissionLocalNetwork: {
QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS");
switch(permission_request.result()) {
case QtAndroidPrivate::Undetermined:
qWarning() << "Permission for posting notifications undetermined!";
break;
case QtAndroidPrivate::Authorized:
qDebug() << "Permission for posting notifications authorized";
break;
case QtAndroidPrivate::Denied:
qWarning() << "Permission for posting notifications denied!";
case PlatformPermissions::PermissionBackgroundLocation: {
if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 10)) {
emit s_instance->backgroundLocationPermissionChanged();
break;
}
auto permissionRequest = QtAndroidPrivate::requestPermission("android.permission.ACCESS_BACKGROUND_LOCATION");
permissionRequest.then(qApp, [platformPermission](QtAndroidPrivate::PermissionResult result) {
switch(result) {
case QtAndroidPrivate::Undetermined:
qWarning() << "Permission for background location undetermined!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
case QtAndroidPrivate::Authorized:
qDebug() << "Permission for background location authorized";
break;
case QtAndroidPrivate::Denied:
qWarning() << "Permission for background location denied!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
}
emit s_instance->backgroundLocationPermissionChanged();
});
break;
}
case PlatformPermissions::PermissionLocalNetwork: {
auto permissionRequest = QtAndroidPrivate::requestPermission("android.permission.NEARBY_WIFI_DEVICES");
permissionRequest.then(qApp, [platformPermission](QtAndroidPrivate::PermissionResult result) {
switch(result) {
case QtAndroidPrivate::Undetermined:
qWarning() << "Permission for local network undetermined!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
case QtAndroidPrivate::Authorized:
qDebug() << "Permission for local network authorized";
break;
case QtAndroidPrivate::Denied:
qWarning() << "Permission for local network denied!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
}
emit s_instance->localNetworkPermissionChanged();
});
break;
}
case PlatformPermissions::PermissionNotifications: {
@ -199,128 +274,27 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi
break;
}
QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS");
auto result = permission_request.result();
switch(result) {
case QtAndroidPrivate::Undetermined:
qWarning() << "Permission for posting notifications undetermined!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
case QtAndroidPrivate::Authorized:
qDebug() << "Permission for posting notifications authorized";
break;
case QtAndroidPrivate::Denied:
qWarning() << "Permission for posting notifications denied!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
}
emit s_instance->notificationsPermissionChanged();
auto permissionRequest = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS");
permissionRequest.then(qApp, [platformPermission](QtAndroidPrivate::PermissionResult result) {
switch(result) {
case QtAndroidPrivate::Undetermined:
qWarning() << "Permission for posting notifications undetermined!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
case QtAndroidPrivate::Authorized:
qDebug() << "Permission for posting notifications authorized";
break;
case QtAndroidPrivate::Denied:
qWarning() << "Permission for posting notifications denied!";
s_instance->m_requestedButDeniedPermissions.append(platformPermission);
break;
}
emit s_instance->notificationsPermissionChanged();
});
break;
}
default:
qCWarning(dcPlatformPermissions()) << "Requested platform permission" << platformPermission << "but is not implemented yet.";
break;
}
emit s_instance->locationPermissionChanged();
emit s_instance->backgroundLocationPermissionChanged();
emit s_instance->notificationsPermissionChanged();
// if (permissionMap().contains(permission)) {
// qCDebug(dcPlatformPermissions()) << "Requesting permissions:" << permissionMap().value(permission);
// qApp->requestPermission(QCameraPermission{}, [](const QPermission &permission) {
// if (permission.status() == Qt::PermissionStatus::Granted)
// takePhoto();
// });
// // QtAndroid::requestPermissions({permissionMap().value(permission)}, &permissionResultCallback);
// }
}
// void PlatformPermissionsAndroid::openPermissionSettings()
// {
// qCDebug(dcPlatformPermissions()) << "Opening permission dialog.";
// QJniObject packageName = QtAndroid::androidContext().callObjectMethod("getPackageName", "()Ljava/lang/String;");
// QString packageUri = "package:" + packageName.toString();
// QJniObject uri = QJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", QJniObject::fromString(packageUri).object());
// QAndroidIntent intent = QAndroidIntent("android.settings.APPLICATION_DETAILS_SETTINGS");
// intent.handle().callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", uri.object());
// intent.handle().callObjectMethod("addFlags", "(I)Landroid/content/Intent;", FLAG_ACTIVITY_NEW_TASK);
// QtAndroid::androidContext().callMethod<void>("startActivity", "(Landroid/content/Intent;)V", intent.handle().object());
// }
// QHash<PlatformPermissions::Permission, QStringList> PlatformPermissionsAndroid::permissionMap() const
// {
// QOperatingSystemVersion osVersion = QOperatingSystemVersion::current();
// if (osVersion.majorVersion() <= 9) {
// 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"}}
// };
// }
// 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
// {
// PermissionStatus status = PermissionStatusGranted;
// QStringList androidPermissions = permissionMap().value(permission);
// qCDebug(dcPlatformPermissions()) << "Checking permission" << permission << "(" << androidPermissions << ")";
// foreach (const QString androidPermission, androidPermissions) {
// if (QtAndroid::shouldShowRequestPermissionRationale(androidPermission) || m_requestedButDeniedPermissions.contains(androidPermission)) {
// qCDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "denied";
// status = PermissionStatusDenied;
// }
// if (QtAndroid::checkPermission(androidPermission) == QtAndroid::PermissionResult::Denied) {
// 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;
// }
// 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->locationPermissionChanged();
// emit s_instance->backgroundLocationPermissionChanged();
// emit s_instance->notificationsPermissionChanged();
// }

View File

@ -33,11 +33,14 @@
PlatformPermissions *PlatformPermissions::instance()
{
#ifdef Q_OS_ANDROID
return new PlatformPermissionsAndroid();
static PlatformPermissionsAndroid instance;
return &instance;
#elif defined Q_OS_IOS
return new PlatformPermissionsIOS();
static PlatformPermissionsIOS instance;
return &instance;
#else
return new PlatformPermissions();
static PlatformPermissions instance;
return &instance;
#endif
}