Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to request the permissions in runtime



  • I am trying to develop an app, but I can not find the way to request the runtime permissions on android 6. Can someone help me?


  • Moderators

    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.



  • @sierdzio How do I do it with java? I tried some codes but the application hangs


  • Moderators

    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 Thanks, I will tray


  • Moderators

    @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();
    }
    

  • Moderators

    @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.


  • Moderators

    @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.


  • Moderators

    Hm, maybe it got fixed in 5.11.2, good to know.



  • @J.Hilk

    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..


  • Moderators

    @PSI_lbc said in How to request the permissions in runtime:

    @J.Hilk

    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.


  • Moderators

    @elim2g mmh, interesting,
    do you have a minimal compile-able example we could test?


Log in to reply