breautek commented on issue #560:
URL:
https://github.com/apache/cordova-plugin-file/issues/560#issuecomment-1454808981
> I presume the LocalFileSystem.PERSISTENT can be replaced with
cordova.file.externalDataDirectory or similar? Or is PERSISTENT the only way to
make this work?
Not quite. First I want to make clear of two filesystem concepts that
Android has:
1. `Internal` storage. This is a embedded chip that is tied to the device
itself.
2. `External` storage. This is an independent storage medium that may or may
not exist on the device, or it may change at any time. Most android devices
will emulate external storage (in which case it will have a
`/storage/emulated/` path), but if the user inserts an SD card, then the
external storage path may change to `/sdcard`.
Now `Internal` storage is protected but every application has it's own
internal storage sandbox that it basically as free reign over for the most
part. Some directories or files may be read-only, such as the
`cordova.file.applicationStorageDirectory`, which is the installation directory
of your app, which you don't have permission to update, however you can create
folders in this path.
`LocalFileSystem.PERSISTENT` is part of the (now defunct) W3C FileSystem
API, which the file plugin implements. This is an implementation detail, but
currently this uses the `Internal` storage directory. It's the equivalent to
`cordova.file.dataDirectory + "files/"`. If you were to use the File Explorer
tool, you'll see the following folder path: `/data/data/<app_id>/files/files/`.
For Android, all of the `cordova.file` directory APIs will refer to a
`Internal` storage path, while all `cordova.file.external*` constants will
refer to an `External` storage path.
You're pretty much free to create any directory structure inside internal
storage without permissions, within your app_id sandbox.
`External` storage has gone through several changes (and further changes are
incoming in API 33). And access depends on several factors. For example, every
Android app has an external data directory,
`cordova.file.externalDataDirectory`, which like Internal storage, you could
read and write to without any permissions.
Inside `cordova.file.externalRootDirectory` you'll see the several
directories for different media as well as `Downloads` directory, and a few
others, which I'm going to refer to these as "External Media" directories.
Android API 28 and earlier, your app could do a lot of different things,
everywheres on external storage, including messing around with other app's
external storage, as long as you had the `READ/WRITE_EXTERNAL_STORAGE`
permission.
Android API 29 have made changes to make external storage slightly more
secure, which including locking down some directories. `WRITE_EXTERNAL_STORAGE`
no longer does anything, and you may write to External Media directories
without any special permissions however you may not overwrite files that
already exists if it's owned by a different application. Reading files still
requires the `READ_EXTERNAL_STORAGE` permission. On API 29, developers could
make use of a `requestLegacyExternalStorage` flag to revert the behaviour back
to API 28 behaviour, but this is a request which the OS may reject. I believe
it only honours it for users that already had your app installed, so in
otherwords, fresh app installs will not honour this request. Lastly, **API 29
is specifically broken
with the file plugin because Android does not implement a filesystem API
for external storage**. This means if the app wants to access the external file
storage, it must use the native MediaStorage APIs, which the file plugin does
not and cannot really implement.
Starting with API 30, Android **does** implement filesystem API for external
storage which allows for third-party libraries and native code to access the
external storage again, which also "fixes" this plugin so to speak. The scoped
storage changes that came in API 29 however still applies.
Starting with API 33 (currently not supported), `READ_EXTERNAL_STORAGE` will
no longer work and instead they have `READ_MEDIA_*` permissions for images,
audio, and video.
> I can write to cordova.file.externalRootDirectory + "MyNewFolder" and
download my file there. Ok, so I got all that working again.
Android doesn't make clear but they have said that some directories will be
inaccessible. Therefore I wouldn't rely on using custom directories in external
root, and instead either use your app's internal or external directory.
Therefore I'd consider preparing a migration strategy if necessary.
> However for iOS, I am continually perplexed. For iOS I have now used both
cordova.file.externalDataDirectory and cordova.file.dataDirectory.....
I'm significantly less knowledgable with iOS, and I'm not sure how
`externalDataDirectory` behaves for iOS (it's not documented...) but I do know
that iOS does not have an internal/external storage concept like Android. iOS
storage model is far more simple. Your app has an filesystem sandbox that is
completely private. It's comparable to Android's internal storage concept.
Sharing files between apps happens via non-filesystem APIs I believe, there is
no way so share files between apps using purely the filesystem. So in
otherwords, a browser app downloading a file may write to it's app storage
sandbox, but use a non-filesystem API to share it in a more public place... For
example, in order for the iOS to move a file to a shared location, it must use
something like
[UIDocumentPickerViewController](https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller?language=objc)
which brings up a save dialog and the user chooses where to put the file. The
iOS app itself d
oes not have direct access to anything outside of it's sandbox. I don't
believe anything like this is implemented in the file plugin, as it's aimed to
be... a filesystem API.
Hope this knowledge helps somehow.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]