nativescript-external-storage v1.0.0
Nativescript External Storage
This plugin allows Android apps to easily work with files and folders in external storage. It works on all Android versions, including 11+.
Features
- Save to external storage
- Import to app's files in internal storage
- Check if a file exists
- Delete a file
- List directories and files
- Check permission to modify a file (Android 11)
Instalation
tns plugin add nativescript-external-storage
Usage
var storage = require("nativescript-external-storage");
First instructions
This plugin works by copying files to and from internal and external storage. All files you want to save inside a folder in external storage must come from your /data/com.package.name/files
. For example, if you want to transfer "my-image.jpg" to /Pictures
, that file must be inside your app internal storage located at /data/com.package.name/files
. You can get the direct path to your app files directory by using this: application.android.context.getFilesDir()
, but feel free to use any method you want, as long as it returns the right path to the files folder inside your app internal storage. When you import files to your app, they'll be saved in that folder too.
Android 11
With Android 11, apps don't need to request any permission to use public folders such as Documents, Download, Pictures, Music, etc., but your app can only read and modify the files it created. For example, if someone installs your app and saves a backup in /Documents/backup, and then uninstalls the app, when he installs it again, that backup file can't be used by the app anymore. So let your users know about this important detail.
Also, except for Documents and Download, only the appropriate files format can be saved in Pictures (images), Music (audio), Movies (videos), and other public folders.
Android 10 and below
On Android 10 devices, you can disable scoped storage if you want to by adding the following to your AndroidManifest.xml:
<application android:requestLegacyExternalStorage="true">
For all the other versions below 10, you also need to add the following lines:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
And, of course, you need to request user permission in your app code. You can use the nativescript-permissions plugin for that task.
List of arguments
Before presenting the functions that you can use in this plugin, let's know their arguments first.
folder
The target folder with or without a subfolder where you want to save files. If the subfolder doesn't exist, it'll be created automatically.
Examples:
"/Documents"
"/Documents/myfolder"
"/Pictures"
Always begins the string with a slash "/" but don't include one at the end. If you pass an empty string "", files will be saved in the root directory on Android 10 and below. On Android 11, apps can't use the root directory.
fileName
When saving to external storage, it's the name of the file located in /data/com.package.name/files
. When importing to your apps folder, it's the name of the file located in the external storage.
Examples:
"myfile.txt"
"myimage.jpg"
pathList
By default, the plugin will always try to use the following paths to external storage: /storage/emulated/0
and /sdcard
. I never found a device where these two paths wouldn't work. But in case you need different paths, you can pass an array with as many items as you want.
Example:
var myPaths = ["/path1", "/path2", "/path3"];
Always begin the string with a slash "/" but don't include one at the end.
type
This argument is only used in the storage.content
function when you want to retrieve a list of files or directories. So you should specify if it's "file" or "directory" what you want.
Functions
storage.save
It copies a file from /data/com.package.name/files
to external storage.
storage.save(folder, fileName, pathList);
Example:
var file = storage.save("/Documents", "my-file.doc");
if (file) {
// File copied to external storage
}
If a file with the same name already exists inside the destination folder, it'll be overwritten on Android 10 and below, but on Android 11, the function will fail and return undefined.
storage.import
It copies a file from external storage to /data/com.package.name/files
. It must be used in conjunction with storage.check
. In this case, you must pass the string "check" as the fourth argument of the Check function.
storage.check(folder, fileName, pathList, "");
storage.import(fileName, filePath); // The file path is returned by the storage.check function.
Example:
var file = storage.check("/Pictures", "my-picture.jpg", "", "check");
if (storage.import("my-picture.jpg", file)) { // The output file can have a different name if you want.
// File imported to internal apps folder
}
On Android 11, no file will be imported if your app doesn't own the file.
storage.check
It checks if a file exists. It’ll check all files, including the ones that were not created by your app. It’s useful to avoid conflicts in file names because, on Android 11, an app can’t override a file it didn’t create.
storage.check(folder, fileName, pathList);
Example:
var file = storage.check("/Download", "my-file.txt");
if (file) {
// File exists
}
storage.content
It returns an array with a list of files or directories. On Android 11, you can only retrieve files created by your app.
storage.content(type, folder, pathList);
Example:
var files = storage.content("file", "/Documents");
var directories = storage.content("directory", "/DCIM");
storage.delete
It deletes any file on Android 10 and below, and only the files created by your app on Android 11. It must be used in conjunction with storage.check
. In this case, you must pass the string "check" as the fourth argument of the Check function.
storage.check(folder, fileName, pathList, "");
storage.delete(filePath); // The file path is returned by the storage.check function.
Example:
var file = storage.check("/Documents", "my-file.doc", "", "check");
if (storage.delete(file)) {
// File deleted
}
storage.hasPermission (for Android 11 and above)
Before your app can do anything with a file on Android 11, it first needs to know if it has permission. For example, an app can't read, replace, or rename a file without being the owner of the file. Avoid unecessary calls to functions that will always return false by checking permission first.
This function must be used in conjunction with storage.content
.
storage.content(type, folder, pathList);
storage.hasPermission(fileName, fileList); // The list of files is returned by the storage.content function.
Example:
var array = storage.content("file", "/Documents");
var permission = storage.hasPermission("file.txt", array);
if (permission) {
// Yes, I can work with that file.
}
Donate 
It's hard to keep plugins updated and bug-free without financial support. If you found this plugin useful, consider donating.
4 years ago