Cannot grant MANAGE_EXTERNAL_STORAGE permission on Android 11
-
I am developing an application that uses bluetooth and file read write permissions. I'm kinda completed my app in ABI 28 and on nither real device nor virtual device have any problem with Android 11.
While uploading the app to google play console, Google wanted apps that targets ABI 30 minimum (soon 31 i guess). While trying to target ABI 30, i've come across some problems which have solutions or workarounds. Those problems were;
-
target ABI selection was malfunctioning (Qt built my app in ABI 28 while manifest file target selection was 30). I solved that problem with ANDROID_TARGET_SDK_VERSION = 30 line in .pro file
-
When i built my app in ABI 30, some sign version problem occured. (this problem : https://bugreports.qt.io/browse/QTBUG-91255) i solved problem with manual signing with a batch file like this:
set file_path=C:\Drive\blalba\android-build\build\outputs\apk\release\android-build-release-signed.apk set output_file=C:\Drive\blabla\android-build\build\outputs\apk\release\android-build-release-manually-signed.apk set key_store_file=C:\Drive\blabla\bla.keystore set key_store_alias=key1 set keystore_password=pass:"mypassword123" C:\Users\bla\AppData\Local\Android\Sdk\build-tools\30.0.2\zipalign.exe -v 4 %file_path% %output_file% C:\Users\bla\AppData\Local\Android\Sdk\build-tools\30.0.2\apksigner.bat sign --ks %key_store_file% --ks-key-alias %key_store_alias% --ks-pass %keystore_password% --key-pass %keystore_password% --verbose %output_file% pause
after manually signing the apk, i could install apk to my real device with android 11. Then i am stucked.
My app creates directories and reads/writes files in the /storage/emulated/0/ directory to be able to make files user accessible. These files json or xlsx files. I grant the write permission "android.permission.WRITE_EXTERNAL_STORAGE" in my cpp code. The cpp code:
QtAndroid::PermissionResult result = QtAndroid::checkPermission(QString("android.permission.WRITE_EXTERNAL_STORAGE")); if(result == QtAndroid::PermissionResult::Denied){ qWarning()<<"file permission denied"; QtAndroid::PermissionResultMap resultHash = QtAndroid::requestPermissionsSync(QStringList({"android.permission.WRITE_EXTERNAL_STORAGE"})); if(resultHash["android.permission.WRITE_EXTERNAL_STORAGE"] == QtAndroid::PermissionResult::Denied) { show_fullscreen_permission_info(sbgp::FILE_PERMISSION_DENIED); } }
.
.
.But with ABI 30, android forces developers to use scoped storage which is not ok for me. Because i wanna give my files to user. So, i'm trying to grant MANAGE_EXTERNAL_STORAGE permission with same piece of code and it does nothing at all. Because of i do not have write permission, my app is not working properly and i cannot publish it in google play.
What should i do dear Qt?
And i wonder, what is the officially supported max android ABI right now in Qt. Google will enforce us to target minimum ABI 31, Should i leave the Qt to develop google play publishable apps ?
My development environment:
- Qt 5.15.2
- C coplier : Android Clang (C, arm, NDK 21.3.6528147)
- C++ coplier : Android Clang (C++, arm, NDK 21.3.6528147)
- CMake Tool : Cmake 3.21.1(Qt)
- Qt Creator 5.0.2 Based on 5.15.2 (MSVC 2019, 64 bit) built on 30.2021 01:26:25
-
-
I am developing an application that uses bluetooth and file read write permissions. I'm kinda completed my app in ABI 28 and on nither real device nor virtual device have any problem with Android 11.
While uploading the app to google play console, Google wanted apps that targets ABI 30 minimum (soon 31 i guess). While trying to target ABI 30, i've come across some problems which have solutions or workarounds. Those problems were;
-
target ABI selection was malfunctioning (Qt built my app in ABI 28 while manifest file target selection was 30). I solved that problem with ANDROID_TARGET_SDK_VERSION = 30 line in .pro file
-
When i built my app in ABI 30, some sign version problem occured. (this problem : https://bugreports.qt.io/browse/QTBUG-91255) i solved problem with manual signing with a batch file like this:
set file_path=C:\Drive\blalba\android-build\build\outputs\apk\release\android-build-release-signed.apk set output_file=C:\Drive\blabla\android-build\build\outputs\apk\release\android-build-release-manually-signed.apk set key_store_file=C:\Drive\blabla\bla.keystore set key_store_alias=key1 set keystore_password=pass:"mypassword123" C:\Users\bla\AppData\Local\Android\Sdk\build-tools\30.0.2\zipalign.exe -v 4 %file_path% %output_file% C:\Users\bla\AppData\Local\Android\Sdk\build-tools\30.0.2\apksigner.bat sign --ks %key_store_file% --ks-key-alias %key_store_alias% --ks-pass %keystore_password% --key-pass %keystore_password% --verbose %output_file% pause
after manually signing the apk, i could install apk to my real device with android 11. Then i am stucked.
My app creates directories and reads/writes files in the /storage/emulated/0/ directory to be able to make files user accessible. These files json or xlsx files. I grant the write permission "android.permission.WRITE_EXTERNAL_STORAGE" in my cpp code. The cpp code:
QtAndroid::PermissionResult result = QtAndroid::checkPermission(QString("android.permission.WRITE_EXTERNAL_STORAGE")); if(result == QtAndroid::PermissionResult::Denied){ qWarning()<<"file permission denied"; QtAndroid::PermissionResultMap resultHash = QtAndroid::requestPermissionsSync(QStringList({"android.permission.WRITE_EXTERNAL_STORAGE"})); if(resultHash["android.permission.WRITE_EXTERNAL_STORAGE"] == QtAndroid::PermissionResult::Denied) { show_fullscreen_permission_info(sbgp::FILE_PERMISSION_DENIED); } }
.
.
.But with ABI 30, android forces developers to use scoped storage which is not ok for me. Because i wanna give my files to user. So, i'm trying to grant MANAGE_EXTERNAL_STORAGE permission with same piece of code and it does nothing at all. Because of i do not have write permission, my app is not working properly and i cannot publish it in google play.
What should i do dear Qt?
And i wonder, what is the officially supported max android ABI right now in Qt. Google will enforce us to target minimum ABI 31, Should i leave the Qt to develop google play publishable apps ?
My development environment:
- Qt 5.15.2
- C coplier : Android Clang (C, arm, NDK 21.3.6528147)
- C++ coplier : Android Clang (C++, arm, NDK 21.3.6528147)
- CMake Tool : Cmake 3.21.1(Qt)
- Qt Creator 5.0.2 Based on 5.15.2 (MSVC 2019, 64 bit) built on 30.2021 01:26:25
@ovadi here's HowTo grant MANAGE_EXTERNAL_STORAGE.
#define PACKAGE_NAME "package:org.company.package_name" jboolean value = QAndroidJniObject::callStaticMethod<jboolean>("android/os/Environment", "isExternalStorageManager"); if( value == false ) { QAndroidJniObject ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION = QAndroidJniObject::getStaticObjectField( "android/provider/Settings", "ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION","Ljava/lang/String;" ); QAndroidJniObject intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION.object()); QAndroidJniObject jniPath = QAndroidJniObject::fromString(PACKAGE_NAME); QAndroidJniObject jniUri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", jniPath.object<jstring>()); QAndroidJniObject jniResult = intent.callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", jniUri.object<jobject>() ); QtAndroid::startActivity(intent, 0); }
also in Manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
found the solution here: https://bugreports.qt.io/browse/QTBUG-98974?focusedCommentId=680551&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-680551
Important: there's an extra entry in Google Play to request the all-files-access !
requesting and setting the permission works, but I still cannot get files thru StandardPathes, per ex. Pictures or Documents. -
-
If you used QT6 here my pieces codes on this topic -> Holiday gift 2022 pieces codes to facing new Android API SDK >= 30
-
If you used QT6 here my pieces codes on this topic -> Holiday gift 2022 pieces codes to facing new Android API SDK >= 30
@Kafabih BTW: have tried if your solution makes a difference for 5.15. Changed your code:
#define PACKAGE_NAME "package:org.ekkescorner.my.app.test" jboolean value = QAndroidJniObject::callStaticMethod<jboolean>("android/os/Environment", "isExternalStorageManager"); if(value == false) { qDebug() << "requesting ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION"; QAndroidJniObject filepermit = QAndroidJniObject::getStaticObjectField( "android/provider/Settings", "ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION","Ljava/lang/String;" ); QAndroidJniObject pkgName = QAndroidJniObject::fromString(PACKAGE_NAME); QAndroidJniObject parsedUri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", pkgName.object<jstring>()); QAndroidJniObject intent("android/content/Intent", "(Ljava/lang/String;Landroid/net/Uri;)V", filepermit.object<jstring>(),parsedUri.object()); QtAndroid::startActivity(intent, 0); } else { qDebug() << "SUCCESS ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION"; }
works the same as the code from Łukasz Gołębiowski (QTBUG-98974)
requesting and setting the permission works, but I still cannot get files thru StandardPathes, per ex. Pictures or Documents.