1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

ERR_FILE_NOT_FOUND when opening a file in Download in a NativeScript Android app

Discussão em 'Angular' iniciado por Don Knisley, Outubro 11, 2024.

  1. Don Knisley

    Don Knisley Guest

    I have an Angular NativeScript application that needs to download a file from a service, save it in Downloads, and open the file in the device's native viewer. The app supports multiple file types including TXT, PDF, JPG, PNG, and TIF. The file is saving in the Download directory just fine and I'm getting the OS prompt for what app top open it in. Whichever one I choose, usually Chrome, I'm getting an ERR_FILE_NOT_FOUND response when using Utils.openFile(path). This is on an Android emulator, there are no errors in the console or logcat.

    Relevant AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="__PACKAGE__"
    android:versionCode="2023082201"
    android:versionName="0.0.0"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-sdk
    android:minSdkVersion="23"
    android:targetSdkVersion="34"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="31" tools:replace="android:maxSdkVersion"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    <application
    android:name="com.tns.NativeScriptApplication"
    android:allowBackup="true"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:fullBackupContent="false"
    android:usesCleartextTraffic="true"
    android:allowNativeHeapPointerTagging="false">

    <provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true"
    tools:replace="android:authorities">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/filepaths"
    tools:replace="android:resource"
    />
    </provider>
    </application>
    </manifest>


    Code.ts

    public async openFile(): Promise<void> {
    this.pageloader.show();
    const data: Blob = await firstValueFrom(this.myService.GetFile(params));
    try {
    let filePath = '';
    if (isAndroid) {
    filePath = this.writeFile_Android(data, doc.name);
    } else {
    filePath = this.writeFile_iOS(data, doc.name);
    }
    if (filePath) {
    setTimeout(() => {
    this.openFileFromPath(filePath);
    this.pageloader.hide();
    }, 500);
    } else {
    this.pageloader.hide();
    }
    } catch (e) {
    console.log('openFile error');
    this.pageloader.hide();
    console.error(e);
    }
    }
    private writeFile_Android(fileData: Blob, fileName: string): string {
    try {
    fileName = fileName.replace(/\//g, '-');
    fileName = fileName.replace(/ /g, '-');
    fileName = fileName.replace(/:/g, '-');

    const folder = Folder.fromPath(
    android.os.Environment.getExternalStoragePublicDirectory(
    android.os.Environment.DIRECTORY_DOWNLOADS
    ).getAbsolutePath()
    );

    const blob = (Array as any).create('byte', fileData.size);
    for (let i = 0; i < blob.length; i++) {
    blob = (fileData as any)._buffer;
    }

    let docFile: fileSystem.File = folder.getFile(fileName);
    docFile.writeSync(blob);

    return docFile.path;
    } catch (e) {
    console.log('writeFile_Android error');
    console.error(e, e.stack);
    return null;
    }
    }
    // import { Utils } from '@nativescript/core';
    private openFileFromPath(path: string) {
    console.log(`path: ${path}`);
    // content://com.[company].[product].local.provider/external/Download/Text-Document.txt
    try {
    let opened = Utils.openFile(path);
    if (!opened) {
    console.error(`download file not opened '${path}'`);
    }
    } catch (e) {
    console.log('openFileFromPath error');
    console.error(e, e.stack);
    }
    }


    Versions

    Angular CLI: 16.2.16
    Node: 18.15.0
    Package Manager: npm 9.5.0
    OS: win32 x64

    Angular: 14.3.0
    ... animations, common, compiler, compiler-cli, core, forms
    ... platform-browser, platform-browser-dynamic, router

    Package Version
    ---------------------------------------------------------
    @angular-devkit/architect 0.1402.13
    @angular-devkit/build-angular 14.2.13
    @angular-devkit/core 14.2.13
    @angular-devkit/schematics 16.2.16 (cli-only)
    @ngtools/webpack 14.2.13
    @schematics/angular 16.2.16 (cli-only)
    rxjs 7.8.1
    typescript 4.8.4
    zone.js 0.12.0


    Frankly I'm at a loss on what to try. Four members of my team spent six hours on it and only got the file saving to Download. This code worked and was released months ago. I'm expecting the file to be vied in the system viewer.

    Continue reading...

Compartilhe esta Página