nativescript-angular: Cant download file properly to a user accessible location

I am using the HTTP library to attempt to download a file.

In short, I want to download a file, from a URL, to my device in a place where the user can access it easily.

For simplicity in getting it working the first time I am using the example from the docs.

This is the code I am using:

download (id) {
        console.log('Download Started');
        getFile("https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png").then(function (r) {
            console.log(r.path);
        }, function (e) {
            //// Argument (e) is Error!
        });
    }

This outputs the path it was saved at as being:

/data/user/0/com.myapp.example/files/logo.png

When I try to go to this location on a file browser from the play store It is nowhere to be found.

Can anyone shed anymore light on this?

Obviously, I want this to work the same on ios and Android but I am testing on Android atm.

Thanks

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 20

Commits related to this issue

Most upvoted comments

@NickIliev How to use http getFile function with nativescript angular? I have looked in NS Angular http class, but its not having the getFile funtion.

@RyanSMurphy, in order to access the native APIS, thought any TypeScript enabled project you will need the TypeScript declaration files for the native APIs. The good news is that you don’t need to generate those files as we are providing them with tns-platform-declarations package. However to enable them under Angular-2 project requires some additional steps as follows:

npm i tns-platform-declarations --saveDev

then open tsconfig.json and add the lib option

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "experimentalDecorators": true,
        "lib": [
            "es2016"
        ]
    }
}

and finally open references.d.ts and modify its tcontent to look like this

/// <reference path="./node_modules/tns-core-modules/tns-core-modules.es2016.d.ts" />

/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />

declare type Comment = any;
declare type CloseEvent = any;
declare type Document = any;
declare type DocumentFragment = any;
declare type Element = any;
declare type History = any;
declare type HTMLAnchorElement = any;
declare type HTMLCollection = any;
declare type HTMLDocument = any;
declare type HTMLElement = any;
declare type HTMLInputElement = any;
declare type HTMLScriptElement = any;
declare type HTMLStyleElement = any;
declare type KeyboardEvent = any;
declare type Location = any;
declare type MessageEvent = any;
declare type MouseEvent = any;
declare type Node = any;
declare type NodeList = any;
declare type Text = any;
declare type WebSocket = any;

For reference, you can take a look at how these are set in this application.

@RyanSMurphy I see your point and indeed the example above is valid for the in-app folders which are not accessible from “outside” and you want the file to be stored in user accessible folder a,k,a, some of the external storage folders (e.g. Download, or custom folders in the SD cards). Indeed this can not be achieved our-of-the-box however, you can use the native API to get access to public folders.

Note that for Android 6.x and above runtime permissions are required as well (setting WRITE_EXTERNAL_STORAGE from AndroidManifest is not enough you will need to require those permissions runtime)

Here is an example of how to save robots.txt text file in custom folder created in the public Download folder (for Android Nexus 5x in Storate>>Explore>>Download>>customFolder but this path will be different depending on the device and if it is using SD card or not)

We need runtime permissions for Andoird API23+

tns plugin add nativescript-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.INTERNET"/>
    permissions.requestPermission([
        "android.permission.INTERNET",
        "android.permission.READ_EXTERNAL_STORAGE",
        "android.permission.WRITE_EXTERNAL_STORAGE",
    ], "I need these permissions")
        .then(function (res) {
            console.log("Permissions granted!");
        })
        .catch(function () {
            console.log("No permissions - plan B time!");
        });
}

Then creating the file in the user accessible folder Download/customFolder and saving the file robots.txt with the content get from the http request.

    var file: fs.File;
    var fileName = "robots.txt";
    var androidDownloadsPath = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).toString();
    var customFolderPath = fs.path.join(androidDownloadsPath, "customFolder");

    var folder = fs.Folder.fromPath(customFolderPath );
    var path = fs.path.join(customFolderPath , fileName);
    var exists = fs.File.exists(path);

    file = fs.File.fromPath(path);

    httpModule.getFile("http://httpbin.org/robots.txt").then(res => {
        console.log(res);
        var content = res.readTextSync(e=> { console.log(e); });
        return content;
    }).then(cn => {
        file.writeText(cn.toString()).then(() => {
            console.log("content saved!");
        })
    })

@NickIliev - I think this is a good candidate for the code samples?