Open files in assets

时间:2019-01-18 18:16:35

标签: android android-assets

I am stuck trying to open files from assets in my app .apk file. I get a variety of errors each time I do it but currently I have the following error.

2019-01-18 15:51:34.248 8120-8120/com.example.geoff.crosshouse_icu E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.geoff.crosshouse_icu, PID: 8120 android.os.FileUriExposedException: file:///storage/emulated/0/MyFiles/paediatric_drugs.xlsx exposed beyond app through Intent.getData() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1978) at android.net.Uri.checkFileUriExposed(Uri.java:2371) at android.content.Intent.prepareToLeaveProcess(Intent.java:10247) at android.content.Intent.prepareToLeaveProcess(Intent.java:10201) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1667) at android.app.Activity.startActivityForResult(Activity.java:4586)

My current method involves click a navigation menu item to load a spreadsheet from assets called "paediatrics_drugs.xlsx". When that is clicked, the following code is run.

// Copy file from assets
        String filename = "paediatric_drugs.xlsx";
        copyAsset(filename);

        try {
            openFile(filename);
        } catch (IOException e){
            e.printStackTrace();
            Toast.makeText(this, "Intent failed!", Toast.LENGTH_SHORT).show();
        }

The copyAsset(String) method creates a folder in external storage called "MyFiles" and attempts to create a new file there by reading from an InputStream as seen in code below:

private void copyAsset(String filename) {
    String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyFiles";
    File dir = new File(dirPath);
    if (!dir.exists()) {
        dir.mkdirs();
    }

    AssetManager assets = getAssets();
    InputStream in = null;
    OutputStream out = null;

    try {
        in = assets.open(filename);
        File outFile = new File(dirPath, filename);
        out = new FileOutputStream(outFile);
        copyFile(in, out);
        Toast.makeText(this, "saved!", Toast.LENGTH_LONG).show();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "failed!", Toast.LENGTH_LONG).show();
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

It calls copyFile which takes an input and output stream:

private void copyFile(InputStream input, OutputStream output) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = input.read(buffer)) != -1) {
        output.write(buffer, 0, read);
    }
}

And lastly it calls openFile(String filename) which creates an intent to open the spreadsheet:

private void openFile(String filename) throws IOException {
    String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyFiles";
    File toOpen = new File(dirPath, filename);
    if (toOpen.exists()) {
        Uri uri = Uri.fromFile(toOpen);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(uri, "application/vnd.ms-excel");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        this.startActivity(intent);
    }
}

I am not sure what I am doing wrong, I have looked into several ways of doing it online and have also tried to read from res/raw instead and don't seem to be having any joy. I have the correct permissions established in my manifest, and I am testing in using a minimum Sdk of 15, but running it on a Google Pixel with sdk 28.

Any advice would be much appreciated. If you need me to provide any further information just let me know.

0 个答案:

没有答案