[Interest] Android 13 Devices – API 30+ - SelectFiles – CreateFiles – Qt 5.15
ekke
ekke at ekkes-corner.org
Thu Nov 24 18:24:04 CET 2022
as written below I was able to get Content URIs from FileDialog using a
small test app:
content://com.android.externalstorage.documents/document/primary%3ADocuments%2Fekke.txt
now I wanted to implement this in my customer app. unfortunately now the
Content URIs from FileDialog look different:
content://com.android.providers.media.documents/document/document%3A1000000020
this URI also gives me access to the file content, but I'm missing the
name and suffix
any idea what could cause this different behavior ?
same environment, same QML FileDialog from QtQuick.Dialogs1.3 inside a
QQC2 app
only difference: customer app is using user 10 (Business app)
thx
ekke
Am 23.11.22 um 10:02 schrieb ekke:
>
> 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
>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> https://lists.qt-project.org/listinfo/interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20221124/07a7e06b/attachment.htm>
More information about the Interest
mailing list