简体   繁体   中英

Nativescript: How to save a file in external storage (SD card)

After a lot of googling, and a lot of tries with "out-of-context" code, I'm begging you to help me.

I'm trying to figure out if it's possible to write on the external storage with Nativescript. I'm not interested to write within the application context. So what the docs shows, it's not what i'm looking for.

I've managed to achieve this from a thread on the Nativescript forum:

android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).toString();

It works, it gives me a path, but when I have this path I have no clue of what to do with it. How to create a file inside that path, read it etc.

What I need to achieve is to create a folder that both the user and the application can easily access. The user should be able to access this folder with the builtin files explorer.

The application runs on Angular.

Do you know your external(sd card) path? If it is like /storage/emulated/0, then you could try this to create a folder or file.

import * as fs from "tns-core-modules/file-system";

  let externalPath= fs.path.join(android.os.Environment.getExternalStorageDirectory().getAbsolutePath().toString());
  //Create a folder with known path
  var folder: fs.Folder = fs.Folder.fromPath(sdCardPath+"/test");
  //Create a file 
  var testFile: fs.File = folder.getFile("test.txt");
  console.log("Path " + folder.path)

User should be able to access this fold and file. It is in device internal storage which is "external" folder.

I still try to figure out how to get access to sd card but hope above code work for you.

I really struggled with this one on Android device and in the end it was due to:

  1. Not making sure the required permissions has been granted by the user in the app
  2. Using "Android File Transfer" on my Macbook to verify the files have been created and to download them

tns info

nativescript 6.0.3
tns-core-modules 6.0.7
tns-android 6.0.2 

tns plugins

nativescript-permissions 1.3.7

example code

        import * as fs from "tns-core-modules/file-system"

        ...

        // First get the required permissions
        // Note: this permissions should also be in your AndroidManifest.xml file as:
        //   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        const permissions = require('nativescript-permissions')
        permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
        .then(() => {
            console.log('Required Android permissions have been granted');
        })
        .catch(() => {
            console.error('Required Android permissions have been denied!');
        });

        // Get the publicly accessable Downloads directory path
        const sdDownloadPath = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).toString()
        console.log('sdDownloadPath: ' + sdDownloadPath)

        // Get a specific folder in that path (will be created if it does not exist)
        const myAppFolder = fs.Folder.fromPath(fs.path.join(sdDownloadPath, 'myApp'))
        console.log('myApp path: ' + myAppFolder.path)

        // Get a file in that path (will be created if it does not exist)
        // Note: In this case we try to get a unique file every time this code is run
        let date = new Date()
        date = date.toISOString().replace('.', '')
        const myFile = myAppFolder.getFile(`myfile_${date}.txt`) 
        console.log('myFile path: ' + myFile.path)

        // Write some data to this new file
        myFile.writeText('Hello duder 123')
        .then(() => {})
        .catch((err) => console.log(`Error writing to file: ${err}`))

        // Try and read back the data that was written
        myFile.readText()
        .then((res) => {
            console.log(`Text read back: ${res}`)
        }).catch((err) => {
            console.log(err.stack);
        });

        // List all files in the myApp folder
        myAppFolder.getEntities()
        .then((entities) => {
            // entities is array with the document's files and folders.
            entities.forEach((entity) => {
                console.log(entity)
            });
        }).catch((err) => {
            console.log(err.stack);
        });

android file transfer issue

One problem I wasted a lot of time on was that I could see the files with getEntities() but could not see them when using the 3rd party tool "Android File Transfer (AFT)" on Mac. I eventually stumbled across "Android Studio's -> Device File Explorer" and could see all my created files and folders with it so realised the issue is with AFT.

I now make use of Airdroid to browse and download device files.

applicable reference

https://docs.nativescript.org/angular/ng-framework-modules/file-system (angular docs but relevant to nativescript-vue as well)

我有同样的问题,最后通过在 AndroidManifest.xml 文件中添加android:requestLegacyExternalStorage="true"来解决它,请按照此处的线程进行操作

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM