[Interest] Android 13 Devices – API 30+ - SelectFiles – CreateFiles – Qt 5.15

ekke ekke at ekkes-corner.org
Wed Nov 23 10:02:52 CET 2022


In one of my apps the user must be able to select one or more files from 
shared data and also to create a new file in a selected directory.

Up to API 29 I did this using QStandardPathes, per ex. for 
PicturesLocation and DocumentsLocation and have built my own 
CustomFileDialog.

With API30 QStandardPathes only work with AppDataLocation, but not with 
external shared data because of ScopedStorage.

Qt support for ScopedStorage is still work-in-progress 
(https://bugreports.qt.io/browse/QTBUG-98974 
<https://bugreports.qt.io/browse/QTBUG-98974>)

Tried to use MANAGE_EXTERNAL_STORAGE, because the app is a DropBox-like 
app to manage files from shared network drives or SharePoints.

cpp:

#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);

QAdroidJniObject 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);

}

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"/>

App asks for permission and sets permission – controlled at 
settings-apps-special apps-apps with all files access.

But nothing changed – QStandardPathes still gives no access to files – 
only for internal AppDataLocation.

Any idea what could be missed to get the “old” behaviour back using 
MANAGE_EXTERNAL_STORAGE permission ?

Looked for workarounds and tried KDAB SharedStorage Library:

https://www.kdab.com/android-shared-storage-qt-wrapper/ 
<https://www.kdab.com/android-shared-storage-qt-wrapper/>

https://github.com/KDAB/android/tree/master/shared_storage 
<https://github.com/KDAB/android/tree/master/shared_storage>

YEP - it works, but there’s a drawback:

selecting files only selects one file – haven’t found a way to select 
multiple files using KDABs SharedStorage library and this is essential 
for users.

Selecting a folder and then creating a file inside the folder works great.

Then I found out, that QDir and QFile not only support file pathes, but 
also Content URIs 
(https://developer.android.com/reference/android/content/ContentUris).

This is not documented yet, because full ScopedStorage support not ready 
yet (https://bugreports.qt.io/browse/QTBUG-99664 
<https://bugreports.qt.io/browse/QTBUG-99664>)

But the current implementation helps if using the QML FileDialog on 
Android 

Select multi files: Using the QML FileDialog I can see the files from 
different external locations and I can select multi files, what was 
missing from KDABs SharedStorage. I’m getting a list of ContentUris and 
can then use QFile directly using the ContentUris 

Create File in folder: I can select a folder, was asked for permission, 
but then trying to create a file inside the selected folder, I’m getting 
errors:

E Qt JAVA : openFdForContentUrl(): No permissions to open Uri

and “Unknown error” from QFile, per ex. using 
"content://com.android.externalstorage.documents/tree/primary%3ADocuments/ekke.txt"

Unfortunately using the QML FileDialog I’m getting some warnings:

W libenbwDOCS_x_arm64-v8a.so: 
qrc:/android_rcc_bundle/qml/QtQuick/Controls/Styles/Android/LabelStyle.qml:94: 
TypeError: Cannot read property 'ENABLED_SELECTED_STATE_SET' of undefined

W libenbwDOCS_x_arm64-v8a.so: 
qrc:/android_rcc_bundle/qml/QtQuick/Controls/Styles/Android/LabelStyle.qml:89: 
TypeError: Cannot read property 'ENABLED_STATE_SET' of undefined

Conclusion:

Selecting a folder and creating a file I can do using KDABs SharedStorage,

Selecting multiple files I can do using QML FileDialog and have to live 
with the warnings.

Any better ideas?

Thx

ekke
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20221123/19aaa811/attachment.htm>


More information about the Interest mailing list