cordova-plugin-file
cordova-plugin-file copied to clipboard
Android: file plugin does not work with content:// URI provided by ACTION_OPEN_DOCUMENT_TREE intent
Bug Report
Problem
See test application: https://github.com/vldmrrr/cordova-plugin-grant-fs-access
What is expected to happen?
The call to resolveLocalFileSystemURL with content:// URI returned by plugin from ACTION_OPEN_DOCUMENT_TREE intent is expected to succeed.
What does actually happen?
The call to resolveLocalFileSystemURL fails with File Not Found error.
Information
https://developer.android.com/training/data-storage/shared/documents-files#grant-access-directory
Command or Code
GrantFsAccess.getDirectory(
"", // URI for the directory that should be opened in the system file picker when it loads.
uri => {
console.log(uri); // URI of the directory that user selected
// Use the resulting URI with file plugin
window.resolveLocalFileSystemURL(
uri,
d=>console.log(d),
err=>console.log(err)
)
}
);
Environment, Platform, Device
Android 12
Version information
$ cordova -v
11.0.0
$ cordova platform
Installed platforms:
android 10.1.2
Available platforms:
browser ^6.0.0
electron ^3.0.0
windows ^7.0.0
$ cordova plugin
cordova-plugin-file 7.0.0 "File"
cordova-plugin-grant-fs-access 1.0 "Request FS access from user"
Checklist
- [x ] I searched for existing GitHub issues
- [ x] I updated all Cordova tooling to most recent version
- [ x] I included all the necessary information above
I dont work with content://
URLs so I cant give any answer or solution, but only feedback from my what I read.
After reviewing the cordova-plugin-grant-fs-access plugin source code, the sample app, and Android docs, I think the plugin is trying to access a restricted directory and failing.
I beleive an empty URI
string, that is being passed into the getDirectory
method, results in targeting the root directory.
From Android Docs, EXTRA_INITIAL_URI
says:
Location should specify a document URI or a tree URI with document ID. If this URI identifies a non-directory, document navigator will attempt to use the parent of the document as the initial location.
I believe the empty string hits the if condition and will attempt to use the parent
, which I suspect is root.
Base on the Access Restrictions of using ACTION_OPEN_DOCUMENT_TREE
on Android 11 (API 30) and higher, the plugin fails on the first two items below.
On Android 11 (API level 30) and higher, you cannot use the ACTION_OPEN_DOCUMENT_TREE intent action to request access to the following directories:
- The root directory of the internal storage volume.
- The root directory of each SD card volume that the device manufacturer considers to be reliable, regardless of whether the card is emulated or removable. A reliable volume is one that an app can successfully access most of the time.
- The Download directory.
Furthermore, on Android 11 (API level 30) and higher, you cannot use the ACTION_OPEN_DOCUMENT_TREE intent action to request that the user select individual files from the following directories:
- The Android/data/ directory and all subdirectories.
- The Android/obb/ directory and all subdirectories.
As I never worked with content
URLs, I dont know the valid test cases.
Also, if there is an issue, I would suggest for a reproduction branch without any third-party plugins. Only cordova-plugin-file
.
After reviewing the cordova-plugin-grant-fs-access plugin source code, the sample app, and Android docs, I think the plugin is trying to access a restricted directory and failing.
Plugin is not failing, user can select existing or create new directory where allowed by the system. Plugin does return URI that is delivered after user selection and consent to write access to selected directory. What fails after that is file plugin's resolveLocalFileSystemURL when used with returned URI
Also, if there is an issue, I would suggest for a reproduction branch without any third-party plugins. Only
cordova-plugin-file
.
cordova-plugin-file
does not provide functionality to invoke ACTION_OPEN_DOCUMENT_TREE intent. Neither cordova itself, as this requires native code, which only achievable with plugin. Invoking intent and returning its result to cordova application is the only function of the plugin
I have the same issue, how would I handle a URL like:
content://com.android.providers.downloads.documents/document/
I always get error 1