cordova-plugin-file icon indicating copy to clipboard operation
cordova-plugin-file copied to clipboard

Android: file plugin does not work with content:// URI provided by ACTION_OPEN_DOCUMENT_TREE intent

Open vldmrrr opened this issue 1 year ago • 3 comments

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

vldmrrr avatar Nov 16 '22 23:11 vldmrrr

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.

erisu avatar Nov 17 '22 05:11 erisu

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

vldmrrr avatar Nov 17 '22 15:11 vldmrrr

I have the same issue, how would I handle a URL like: content://com.android.providers.downloads.documents/document/

I always get error 1

mirko77 avatar Mar 16 '23 15:03 mirko77