Capacitor Filesystem error when I try to read a file in Android 11
Asked Answered
F

1

7

I tried to read a file in my emulator using the function readFile of capacitor filesystem. The file that I trying manipulate it's in emulator's Download folder, and the function return this error:

Error: File does not exist

I also tried to use the copy fucntion, to copy this file to a directory where I can manipulate it, but this function returns me this error:

Error: The source object does not exist

Also I made the tests of permissions in the application, where I got granted.

I searched for this errors online, but without success. Also I used all the parameters of Directory on the functions of my filesystem service, but all the options returns me the same errors. With the same parameters it was possible access filesystem in android 10.

All the tests are make in an emulator Pixel 4 with Android 11 (API30).

In the android.xml, inside the tag application, I added android:requestLegacyExternalStorage="true", and in user-permissions:

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

homePage.ts

with copy

// file_dir_path = file:///storage/emulated/0/Download/
// file_name = file.kml
// path = 'MyApp/project' + this.projectId + '/temp'
return this.filesystem.copyFileToManegeDirectory(file_dir_path + file_name, path + '/teste').then(fileAs64 => {
    console.log(fileAs64).
});

with read

// file_dir_path = file:///storage/emulated/0/Download/
// file_name = file.kml
return readFile(file_dir_path + file_name).then(fileAs64 => {
    console.log(fileAs64);
});

FilesystemService

/** Copy Files */
// fileToCopy = file:///storage/emulated/0/Download/file.kml
copyFileToManegeDirectory(fileToCopy: string, directoryToGo: string): Promise<any> {
    return Filesystem.checkPermissions().then(permission => {
        console.log(permission)
        return Filesystem.copy({
            from: fileToCopy,
            directory: Directory.ExternalStorage,
            to: directoryToGo,
            toDirectory: Directory.External
        }).then(result => {
            console.log(result);
        })
    });
}

/** Read a file and returns a string base 64 */
readFile(path: string): Promise<string> {
    return Filesystem.readFile({
        path: path
    }).then(result => {
        return result.data;
    });
}

I need to know if is possible to get files out of the app’s scoped folder on Android 11. My app needs to import files that can exist anywhere on the device (the user chooses where from).

Ionic info


   Ionic CLI                     : 6.15.1-testing.0 (C:\Users\Gabriel Vieira\AppData\Roaming\npm\node_modules\@ionic\cli)
   Ionic Framework               : @ionic/angular 5.6.8
   @angular-devkit/build-angular : 12.0.2
   @angular-devkit/schematics    : 12.0.2
   @angular/cli                  : 12.0.2
   @ionic/angular-toolkit        : 4.0.0

Capacitor:

   Capacitor CLI      : 3.0.0
   @capacitor/android : 3.0.0
   @capacitor/core    : 3.0.0
   @capacitor/ios     : not installed

Utility:

   cordova-res : 0.15.3
   native-run  : 1.4.0

System:

   NodeJS : v14.16.1 (C:\Program Files (x86)\nodejs\node.exe)
   npm    : 6.14.12
   OS     : Windows 10

npx cap doctor

Latest Dependencies:

  @capacitor/cli: 3.0.1
  @capacitor/core: 3.0.1
  @capacitor/android: 3.0.1
  @capacitor/ios: 3.0.1

Installed Dependencies:

  @capacitor/ios: not installed
  @capacitor/cli: 3.0.0
  @capacitor/android: 3.0.0
  @capacitor/core: 3.0.0

EDIT

Tried to change target SDK to 28 and 29, but the same error ocurred.

The documentation says to add the tag MANAGE_EXTERNAL_STORAGE when I need to access files outside of scoped storage, but this parameter is already included in my manifest and even then I'm not allowed to read anything outside of scoped storage.

While testing for filesystem permissions using checkPermissions() and requestPermissions(), both functions returns publicStorage: 'granted'.

Feil answered 16/6, 2021 at 16:37 Comment(0)
S
4

If you put the correct target in the android/variables.gradle it should work normally, if it doesn't you must open a issue in the Capacitor GitHub page.

ext {
    compileSdkVersion = 29
    targetSdkVersion = 29
    ...
}

And you should not use the MANAGE_EXTERNAL_STORAGE unless you have a very good reason to it, it can become a hassle to deploy in Google Play Store, see the Google's support page for more details. In your AndroidManifest also leave the parameter android:requestLegacyExternalStorage="true", and add the user-permissions:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Selfdevotion answered 22/6, 2021 at 18:24 Comment(2)
I'm using Capacitor 4.x and unfortunately the minimum Sdk version required is 32 now. I can't read files in my code using the Capacitor Filesystem plugin, I get the permission denied error. any ideas? this Scoped Storage business is a mess.Rochelrochell
Still I have the same problem, android 32 ... using capacitor filesystem, but with my tests, I could create a directory, but reading a file it's a Capacitor Exception and Error: File Does not exist... and the file is there. So I don't understand why is so hard to read an external file, even from sdcard ... in my case, I need to read an external JSON file, and for now... it doesn't work.Gimcrackery

© 2022 - 2024 — McMap. All rights reserved.