How to request the permissions in runtime
-
Use QtAndroid::requestPermissions() https://doc.qt.io/qt-5/qtandroid.html#requestPermissions. If possible, don't use the "sync" version, it can hang your app.
And be careful with the callback - in my experience it does not work. So if you want the full solutions, with checking callback results, use Java.
-
In your main activity, in onCreate() function, you can plug the code from Android docs: https://developer.android.com/training/permissions/requesting#java
Once you get that working (you can skip the step with
shouldShowRequestPermissionRationale
initially), you can then transfer that to some other methods which you'd call dynamically, from your app, via JNI. -
@sierdzio said in How to request the permissions in runtime:
Use QtAndroid::requestPermissions() https://doc.qt.io/qt-5/qtandroid.html#requestPermissions. If possible, don't use the "sync" version, it can hang your app.
Are you sure?
I'm using the Sync version in my application, for camera access, and it has jet to fail. I request it before I create the ui, because my app can't work without it.int main(int argc, char *argv[]) { QApplication a(argc, argv); auto result = QtAndroid::checkPermission(QString("android.permission.CAMERA")); if(result == QtAndroid::PermissionResult::Denied){ QtAndroid::PermissionResultMap resultHash = QtAndroid::requestPermissionsSync(QStringList({"android.permission.CAMERA"})); if(resultHash["android.permission.CAMERA"] == QtAndroid::PermissionResult::Denied) return 0; } MainWindow w; return a.exec(); }
-
@J.Hilk said in How to request the permissions in runtime:
@sierdzio said in How to request the permissions in runtime:
Use QtAndroid::requestPermissions() https://doc.qt.io/qt-5/qtandroid.html#requestPermissions. If possible, don't use the "sync" version, it can hang your app.
Are you sure?
I'm using the Sync version in my application, for camera access, and it has jet to fail. I request it before I create the ui, because my app can't work without it.Yes, tested with Qt 5.10, 5.11. It will hand your app if you request coarse location permission. Although very probably it is a bug in QtBluetooth, not in QAndroidExtras.
-
@sierdzio said in How to request the permissions in runtime:
@J.Hilk said in How to request the permissions in runtime:
@sierdzio said in How to request the permissions in runtime:
Use QtAndroid::requestPermissions() https://doc.qt.io/qt-5/qtandroid.html#requestPermissions. If possible, don't use the "sync" version, it can hang your app.
Are you sure?
I'm using the Sync version in my application, for camera access, and it has jet to fail. I request it before I create the ui, because my app can't work without it.Yes, tested with Qt 5.10, 5.11. It will hand your app if you request coarse location permission. Although very probably it is a bug in QtBluetooth, not in QAndroidExtras.
Is that a repeatable error?
Because I'm using Bluetooth LE in my application and I'm also requesting ACCESS_COARSE_LOCATION permission during runtime.
And it's working every time. This is done with the latest Qt 5.11.2
Here is the corresponding source code snippet
#if defined (Q_OS_ANDROID) #include <QtAndroid> const QVector<QString> permissions({"android.permission.ACCESS_COARSE_LOCATION", "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN", "android.permission.INTERNET", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_EXTERNAL_STORAGE"}); #endif int main(int argc, char *argv[]) { qRegisterMetaType<QVector<quint16> >("QVector<quint16>"); qRegisterMetaType<Datagram>(); qRegisterMetaType<QLowEnergyDescriptor>(); qRegisterMetaType<QLowEnergyCharacteristic>(); qRegisterMetaType<TerminalIO::serviceErrors>("serviceErrors"); qRegisterMetaType<uint32_t>("uint32_t"); qRegisterMetaType<int32_t>("int32_t"); qRegisterMetaType<uint8_t>("uint8_t"); #if defined(Q_OS_WIN) || defined(Q_OS_MACOS) qRegisterMetaType<QModbusDevice::Error>("Error"); #endif QGuiApplication app(argc, argv); #if defined (Q_OS_ANDROID) //Request requiered permissions at runtime for(const QString &permission : permissions){ auto result = QtAndroid::checkPermission(permission); if(result == QtAndroid::PermissionResult::Denied){ auto resultHash = QtAndroid::requestPermissionsSync(QStringList({permission})); if(resultHash[permission] == QtAndroid::PermissionResult::Denied) return 0; } } #endif .... }
My test hardware is a Samsung Galaxi tablet with android 7 on it.
-
Hm, maybe it got fixed in 5.11.2, good to know.
-
Thanks for the code snippet.
Haven't tried it yet but it appears to check the permissions established in the manifest(?)..if the permission has been granted, it continues with the next permission in the list..if the permission was not granted or has been changed to NOT granted, the user is asked to grant permission..program exits if needed permission is not granted.
Questions..
Is the const QVector<QString> permissions declaration the same list of permissions as has been declared in the AndroidManifest.xml file?
Is the app responsible for maintaining the Granted/Not Granted status or is that something done by the Android OS in the app Settings?
Does the QtAndroid::requestPermissionsSync function pop a dialog that queries the user for permission or does it just check the permissions as set in App Settings but the OS?
Sorry for the questions. The Android docs aren't that clear and this is the first thread I've found that gives an example..
-
@PSI_lbc said in How to request the permissions in runtime:
Thanks for the code snippet.
I'm happy to help ;-)
Questions..
Is the const QVector<QString> permissions declaration the same list of permissions as has been declared in the AndroidManifest.xml file?
In this example, yes it is the same list as in the manifest file.
Is the app responsible for maintaining the Granted/Not Granted status or is that something done by the Android OS in the app Settings?
You have to check it each time you want to do an operation that requires on of the special permission. Since on of the later Android versions, not sure which one, the user can at any time revoke granted permissions. So you will have to check it regularly/before each use.
Does the QtAndroid::requestPermissionsSync function pop a dialog that queries the user for permission or does it just check the permissions as set in App Settings but the OS?
Both, it checks it first, and if it's not granted makes a standard popup message box, asking for the permission.
Sorry for the questions. The Android docs aren't that clear and this is the first thread I've found that gives an example..
No worries, but for future references, I would suggest creating a new topic rather than waking such an old one from its slumber.
-
@j-hilk said in How to request the permissions in runtime:
Is that a repeatable error?
Because I'm using Bluetooth LE in my application and I'm also requesting ACCESS_COARSE_LOCATION permission during runtime.
And it's working every time. This is done with the latest Qt 5.11.2
Sorry to necro an old thread. I can reproduce this error on the full 5.12.x line of kits. However, if I request the permission before I load my first QML file (ie before I create an instance of QQmlApplicationEngine) then QtAndroid::requestPermissionsSync seems to work perfectly fine for me.
-
@J-Hilk Hello, Sorry for restarting old topic.
If permission was asked using
requestPermissionsSync
method and user denies it, second time onwardsrequestPermissionsSync
doesn't show any popup at all.What to do for asking permission again if user has denied it the first time.
-
Hi,
Ask him to go to the settings and enable them.
-
these permissions are only valid for android how can we do this job on ios
-
@NullByte said in How to request the permissions in runtime:
these permissions are only valid for android how can we do this job on ios
You need to use native code for this.