coder
coder

Reputation: 51

Android FileOutputStream return FileNotFoundException in api level 22

I am trying to download a pdf file from server. I write some code for that. It works fine for api level 21 and >=23 but not working on api 22. Here is the problem:

OutputStream output = new FileOutputStream(fileName);
byte data[] = new byte[1024];

while ((count = input.read(data)) != -1) {
   output.write(data, 0, count);
}

But when it tries to execute

 OutputStream output = new FileOutputStream(fileName); 

it shows

java.io.FileNotFoundException: /storage/emulated/0/data    /data/com.example.test/files/training/training.pdf: open failed: ENOENT (No such file or directory)

This works fine for api level 21 and 23. What went wrong? How can I solve this?

Upvotes: 3

Views: 6769

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007218

before calling FileOutputStream() i am calling this public void createDirectory() { File directory = new File(getFilesDir() + "/training"); if (!directory.exists()) { directory.mkdir(); } }

That is not where you are trying to write the file:

String root = Environment.getExternalStorageDirectory().toString(); String path = path = "/training/training.pdf"; String fileName = fileName=root+"/"+getFilesDir()+path;

As you can see, these do not match.


If you want the file on external storage, the best solution is to get rid of all of that and use getExternalFilesDir(), called on Context (akin to getFilesDir()). This gives you:

  • A unique directory
  • On external storage
  • Where the files will be deleted when your app is uninstalled
  • That does not require permission on Android 4.4+

The next-best solution for external storage is to get rid of all of that and use Environment.getExternalStoragePublicDirectory() as your base, to put the files in a standard location based on their type (e.g., photos, videos, music). These files will survive an uninstall, and this location will require WRITE_EXTERNAL_STORAGE. Plus, you will have to create a unique subdirectory under this root yourself, though typically this is done via a user-friendly display name (e.g., OpenCamera) rather than the package name.

Your directory that you are creating in createDirectory() is perfectly fine, but it is internal storage, so the user cannot access it. If you want to use that, then use the same algorithm to create the File for your FileOutputStream as you are using in createDirectory().

Upvotes: 3

Related Questions