60

This line:

final FileOutputStream outputStream = new FileOutputStream(name);

results in a FileNotFoundException with the message being /2ozjfFQzwv: open failed: EROFS (Read-only file system) where "2ozjfFQzwv" is what I passed as the name of the file.

I have tried this with and without the WRITE_INTERNAL_STORAGE permission. How do I create this file for writing?

Alternatively, I just want to be able to give an image to a new activity, and it is too large to serialize it in an extra. Is there an easier way than writing it to a file then reading from it again? All the questions on here seem to be about writing to an SD card, which I don't want to do because many people don't have SD card slots.

Jonik
  • 74,291
  • 66
  • 249
  • 356
Drew
  • 9,858
  • 10
  • 52
  • 88

8 Answers8

91

I have tried this with and without the WRITE_INTERNAL_STORAGE permission.

There is no WRITE_INTERNAL_STORAGE permission in Android.

How do I create this file for writing?

You don't, except perhaps on a rooted device, if your app is running with superuser privileges. You are trying to write to the root of internal storage, which apps do not have access to.

Please use the version of the FileOutputStream constructor that takes a File object. Create that File object based off of some location that you can write to, such as:

  • getFilesDir() (called on your Activity or other Context)
  • getExternalFilesDir() (called on your Activity or other Context)

The latter will require WRITE_EXTERNAL_STORAGE as a permission.

Is there an easier way than writing it to a file then reading from it again?

You can temporarily put it in a static data member.

because many people don't have SD card slots

"SD card slots" are irrelevant, by and large. 99% of Android device users will have external storage -- the exception will be 4+ year old devices where the user removed their SD card. Devices manufactured since mid-2010 have external storage as part of on-board flash, not as removable media.

serv-inc
  • 29,557
  • 9
  • 128
  • 146
CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
  • 5
    +1 for getFilesDir(), thank you `new BufferedWriter(new FileWriter(getFilesDir() + FILENAME));` – Owen B Dec 23 '13 at 00:14
  • Old devices? As far as I learned from using my Nexus 7 2013, it does not support an SD card... same goes for Nexus 10, perhaps other Nexi. – PawelP Dec 27 '13 at 20:23
  • 12
    @PawełParadowski: All Nexus series devices have external storage. They do not have removable storage. External storage does not mean removable storage. – CommonsWare Dec 30 '13 at 21:46
  • You're definitely right, I should've read your post carefully and thought twice. – PawelP Dec 31 '13 at 15:29
  • For any other visitors from the future, the explanation provided in the docs is that `getExternalFilesDir` will favor removable storage, but `Environment.isExternalStorageEmulated(File)` can determine if it is simply a mount point for a separate internal partition in API 21+. – Abandoned Cart Jan 30 '19 at 17:07
17

try using the permission of WRITE_EXTERNAL_STORAGE You should use that whether there is an external card or not.

This works well for me:

path = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_MOVIES);
File file = new File(path, "/" + fname);

and places my files in the appropriate folder

Martin
  • 4,445
  • 4
  • 23
  • 30
  • 2
    `Starting in API level 19, this permission is not required to read/write files in your application-specific directories returned by getExternalFilesDir(String) and getExternalCacheDir(). ` https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE – androidguy Jan 24 '18 at 01:55
5

Here is simple sample from android developer.

Basically, you can write a file in the internal storage like this :

String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
serv-inc
  • 29,557
  • 9
  • 128
  • 146
Xuan Wu
  • 88
  • 3
5

Adding

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

in manifest and using same as Martin:

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); 
File file = new File(path, "/" + fname);

It worked.

Andrii Abramov
  • 7,967
  • 8
  • 55
  • 79
nobjta_9x_tq
  • 988
  • 11
  • 16
3

As others have mentioned, app on Android can't write a file to any folder the internal storage but their own private storage (which is under /data/data/PACKAGE_NAME ).

You should use the API to get the correct path that is allowed for your app.

read this .

android developer
  • 106,412
  • 122
  • 641
  • 1,128
1

To use internal storage for the application, you don't need permission, but you may need to use: File directory = getApplication().getCacheDir(); to get the allowed directory for the app.

Or:
getCashDir(); <-- should work
context.getCashDir(); (if in a broadcast receiver)
getDataDir(); <--Api 24

Chuck
  • 159
  • 1
  • 7
0

Google have restricted write access to the external sdcard. From API 19 there is a framework called Storage Access Framework which allows you the set up "contracts" to allow write access.

For further info:

Android - How to use new Storage Access Framework to copy files to external sd card

Community
  • 1
  • 1
Theo
  • 1,712
  • 14
  • 26
0

If anyone getting this in unit/instrumentation testing, make sure you call getFilesDir() on the app context, not the test context. i.e. use:

Context appContext = getInstrumentation().getTargetContext().getApplicationContext();

not

Context appContext = InstrumentationRegistry.getContext;
Maverick Meerkat
  • 3,847
  • 2
  • 31
  • 49