0

So the intention is simple, I want to copy the files from the APK's assets folder to the device storage. I achieved that with the below code and it was actually working,

public void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = getAssets().list("sourcedir");
    } catch (IOException e) {
        Log.e("tag", "Failed to get asset file list.", e);
    }
    if (files != null) for (String filename : files) {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(filename);
            File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "TargetFol");
            if (!folder.exists()) {
                folder.mkdirs();
            }
            File outFile = new File(folder, filename);
            out = new FileOutputStream(outFile);
            copyFile(in, out);
        } catch (IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
        }
    }
}

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

getAssets().list("sourcedir") actually lists all the images in the sourcedir in the assets folder of the APK.

But when the method called it throws FileNotFoundException: myfile.png for few files only. For example, I put 5 png in the sourcedir (1.png, 2.png, 3.png, myfile.png, zip.png) All files copied except the myfile.png

I verified that there is no different extension or whatsoever also I had analyzed the APK and all these 5 images are actually there in assets/sourcedir

LOGCAT:

E/tag: Failed to copy asset file: myfile.png
java.io.FileNotFoundException: myfile.png
    at android.content.res.AssetManager.nativeOpenAsset(Native Method)
    at android.content.res.AssetManager.open(AssetManager.java:833)
    at android.content.res.AssetManager.open(AssetManager.java:810)
    at org.pac.pac.act.copyAssets(act.java:97)
    at org.pac.pac.act$2.run(act.java:78)
    at java.lang.Thread.run(Thread.java:919)
2020-10-04 21:06:13.189 30767-30999/packagename E/tag: Failed to copy asset file: myfile2.png
    java.io.FileNotFoundException: myfile2.png
        at android.content.res.AssetManager.nativeOpenAsset(Native Method)
        at android.content.res.AssetManager.open(AssetManager.java:833)
        at android.content.res.AssetManager.open(AssetManager.java:810)
        at org.pac.pac.act.copyAssets(act.java:97)
        at org.pac.pac.act$2.run(act.java:78)

I added another one PNG with the name of myfile2.png and gives the same issue.

UPDATE:

So instead of getting all files I tried to add myfile.png in the inputstream but this also returns the same exception even though the file was exists at the assets/sourcedir folder.

Nithis Kumar
  • 278
  • 2
  • 5
  • 21

1 Answers1

3

Found the solution, it may help others too. So if you're getting multiple files from the subfolder in the assets directory, make sure to include the subfolder name while calling. In my case it was,

in = assetManager.open(filename);

So adding the subfolder name along with the filename fixed the issue.

in = assetManager.open("sourcedir/" + filename);

Thanks to @CommonsWare who let me know this mistake. Fun fact I copied this method from one StackOverflow's question with high upvotes and accepted as an answer but nobody mentioned this issue in the comment. Yeah, it's a simple mistake, my bad.

Nithis Kumar
  • 278
  • 2
  • 5
  • 21