3

I write a Android app on NativeScript.

I have defined required permissions in App_Resources/Android/AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

I know that it's not enough for getting access to storage, so I have requested permission in runtime and check it in System settings.

After downloading some image by browser to Downloads folder I wanna read it in my app. Initially I got a file path by nativescript-mediafilepicker, but for know I use following snippet:

console.log(fs.File.exists('/storage/emulated/0/Download/7zoVG9uML7AyjwHl.png'));
const file = fs.File.fromPath('/storage/emulated/0/Download/7zoVG9uML7AyjwHl.png');
file.readSync(e => console.log('ERROR ' + e));

which print in console:

JS: true
JS: ERROR Error: java.io.FileNotFoundException: /storage/emulated/0/Download/7zoVG9uML7AyjwHl.png: open failed: EACCES (Permission denied)

What I do wrong?

UPDATE I added WRITE_EXTERNAL_STORAGE permission, but it has no effect:

permissions.requestPermissions(p).then(async () => {
  const publicDirectory = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
  const fullPath = `${publicDirectory}/7zoVG9uML7AyjwHl.png`;
  const file = fs.File.fromPath(fullPath);
  file.readSync(e => console.log('ERROR ' + e));
});
JS: ERROR Error: java.io.FileNotFoundException: /storage/emulated/0/Download/7zoVG9uML7AyjwHl.png: open failed: EACCES (Permission denied)
Sergei Krivochenko
  • 567
  • 1
  • 6
  • 21
  • Your should programatically build the path using APIs, `android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();`, now you may pass this path to file system. – Manoj Apr 01 '20 at 01:33
  • I tried to do it, but has no success. I updated my question. – Sergei Krivochenko Apr 01 '20 at 13:22
  • Based on the error it looks like you haven't acquired runtime permission. Can you try reproducing the issue on Playground and share the link? – Manoj Apr 01 '20 at 17:40

4 Answers4

4

So, the solution is:

  1. Add in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  1. Add in AndroidManifest.xml
<application android:requestLegacyExternalStorage="true" ...>

  1. Get file by string path:
const file = fs.File.fromPath('/storage/emulated/0/Download/7zoVG9uML7AyjwHl.png');
file.readSync(e => console.log('ERROR ' + e));
Sergei Krivochenko
  • 567
  • 1
  • 6
  • 21
1

Good morning,

My system details:

  • Plugin: @nativescript-community/ui-document-picker
  • Ubuntu 20.04.3 LTS
  • NativeScript CLI 8.1.4
  • NVM 0.35.3
  • Node v16.13.0
  • NPM 8.1.0
  • Android 11 API Level 30
  • "@nativescript/core": "~8.1.1",
  • "@nativescript-community/ui-document-picker": "^1.1.7",
  • "@nativescript/android": "8.1.1",

When Open filepicker and select a PDF file from downloads folder the file.readSync sayas error:

Error: java.io.FileNotFoundException: /storage/emulated/0/Download/Test.pdf: open failed: EACCES (Permission denied)

And when call file.read says error:

Error: ReadTask returns no result.

This just happens only when targetSdkVersion is set to 30 and not in 29, but now to publish and app in Google App Store needs targetSdkVersion 30.

Thanks

0

I think to access downloads directory you need to add also the write permission to your manifest i.e. android.permission.WRITE_EXTERNAL_STORAGE

then you can build the path to your file progamaticlly using

new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()+"/7zoVG9uML7AyjwHl.png");
quealegriamasalegre
  • 2,887
  • 1
  • 13
  • 35
0
  1. Add in AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:requestLegacyExternalStorage="true" ...>
  1. Use nativescript-permissions plugin : https://www.npmjs.com/package/nativescript-permissions example:
Permissions.requestPermissions(
            [
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE
            ]).then(() => {
               //your code
            };
  1. For Android 10 API 29 you can't use getExternalStorageDirectory() because it was deprecated. more info here: https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory()

Instead of:

const file = fs.File.fromPath('/storage/emulated/0/Download/7zoVG9uML7AyjwHl.png');

Use:

import {Utils} from '@nativescript/core';

const file = Utils.ad.getApplicationContext().getExternalFilesDir(null).getAbsolutePath() +"/7zoVG9uML7AyjwHl.png"