File storage in custom directory?

Using the Capacitor Filesystem API, can I save files in any directory on my device ?
Something like:

Filesystem.writeFile({
        data: 'testcontent', 
        path: 'file://storage/emulated/0/anydir/testfile.txt',
        encoding: Encoding.UTF8,
        recursive: true
)}

I was only able to save files in file:///storage/emulated/0/Android/data/io.ionic.starter/files using the following code:

Filesystem.writeFile({
        data: 'testcontent',
        directory: Directory.External,
        path: 'anydir/testfile.txt',
        encoding: Encoding.UTF8,
        recursive: true
)}

with the file being saved in file:///storage/emulated/0/Android/data/io.ionic.starter/files/anydir/testfile.txt

1 Like

No. It would be anarchy if a given application could stomp all over the files from other applications. The details of what directories are accessible how is OS-specific.

But with the right Capacitor plugin (Java code) it should be possible, right ? I mean in most apps that create data, you can select the specific directory in which you want to save the files.

Not 100% true. Apps these days create their own sandbox storage systems. So when you save something to the “documents” it’s typically a special directory that is isolated to inside the sandbox of that app.

Unlimited access to the file-system is …while not going to fly, especially in todays world of tighter security and needing permissions for things.

2 Likes

Filesystem plugin allows to use absolute file urls, or relative if you pass the directory.

If you don’t pass the directory and use the absolute file url it might work depending on the path, it’s possible to read/write on the paths that “belong” to your app, and some other public “shared” folders.

But those public “shared” folders are no longer available on Android 10 unless you enable the legacy filesystem, and no longer available on Android 11+ even if you enabled the legacy filesystem.

On Android 11+, might be possible to write everywhere if you add (and request) the MANAGE_EXTERNAL_STORAGE permission, which Filesystem plugin doesn’t request.

All the above is just for Android, on iOS there are no public shared folder you can write to, you can only read/write inside your app sandbox. I think in Capacitor 2 the file urls won’t work on iOS, but they will in Capacitor 3 with @capacitor/filesystem plugin.

Your code is probably not working because you have used file://, while the path should start with file:///

3 Likes

How can I make this work? I’ve been developing Ionic apps since v1.0 and right now I’m working on a new project using Ionic 6.x, Angular 12, and Capacitor 3. Everything’s been great at first, but until I started to integrate some native access code.

I’m using the cordova-media-capture plugin for capturing audio/video files. The plugin works fine and returns the MediaFile array. But I’m unable to get access to those files to read their contents for uploads. I think the issue is exactly what you pointed out, the new security restrictions in Android 10+.

I’m using a Xiamo Redmi Note 10 which runs Android 11.
The full path returned in the MediaFile response is something like this:

file:///storage/emulated/0/Android/data/com.android.soundrecorder/files/Jun%2010%2C%2006.21.aac
I’ve tried everything I could think of, nothing works and I’m incredibly frustrated I need help.
I tried reading the file using the cordova-file plugin, Capacitor Filesystem plugin, etc.

Any ideas? Thanks in advance.

1 Like

@arminzia , you should be able to access files located in that folder, using the FileSystem API. The problem was accessing any arbitrary folder. I also ended up using the folder you are referring to (Android/data/package.name/files):

async getFileList() {
    const res = await Filesystem.readdir({
      path: '',
      directory: Directory.External,
    });
    return res.files;
}

async readFile(path: string) { //path = 'myfile.txt'
    const res = await Filesystem.readFile({
      path: path,
      directory: Directory.External,
      encoding: Encoding.UTF8
    });
    return res.data;
}

the plugin needs to be updated to support Android 11+, those locations are no longer available from file urls, so the plugin will have to use newer APIs that allow media files choosing.

1 Like

Thank you, didn’t work. The output files from the media-capture plugin have paths like the one I mentioned. When I try to read the files using cordova-file or the capacitor’s Filesystem plugin, they both say the file doesn’t exist. I think it’s the Android 11 issue, the plugins need an update. How incredibly frustrating!

Thank you. Is there a workaround or any other solution?

For our project, we only need some basic native access, capturing audio, video, and images.
The Capacitor Camera plugin works very well for images. But I’ve been struggling with audio/video captures. The cordova plugins used to work fine before Android 10, now it’s a dead-end it seems.

I can only hope the Capacitor team roles out official plugins for the essentials eventually.