3

I write a file in internal memory:

byte[] data = ... // (A buffer containing wav data)
String filename = context.getFilesDir().getAbsolutePath() + "/newout.wav";
File file = new File(filename);
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();

Then I try to play it:

MediaPlayer player = new MediaPlayer();
player.setDataSource(filename);
player.prepare();
player.setLooping(false);
player.start();

But the prepare() fails:

java.io.IOException: Prepare failed.: status=0x1

I checked the file and saw that it's permission is -rw-------. I changed it to -rw-r--r--, after that it was being played successfully.

So how come my app can write a file, but can't read it? And how can I make the FileOutputStream to set the permissions right?

Mousa
  • 2,190
  • 3
  • 21
  • 34

2 Answers2

2

To change programaticaly the file permissions to -rw-r--r-- you need to do smoething like this:

Process process = null;
DataOutputStream dataOutputStream = null;

try {
    process = Runtime.getRuntime().exec("su");
    dataOutputStream = new DataOutputStream(process.getOutputStream());
    dataOutputStream.writeBytes("chmod 644 FilePath\n");
    dataOutputStream.writeBytes("exit\n");
    dataOutputStream.flush();
    process.waitFor();
} catch (Exception e) {
    return false;
} finally {
    try {
        if (dataOutputStream != null) {
            dataOutputStream.close();
        }
        process.destroy();
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
Gabriella Angelova
  • 2,985
  • 1
  • 17
  • 30
1

If you open a file, the default mode is Context.MODE_PRIVATE, e.g. as in

File file = new File(context.getFilesDir(), filename);

String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;

try {
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
  outputStream.write(string.getBytes());
  outputStream.close();

} catch (Exception e) {
  e.printStackTrace();
}

(taken from the documentation). Modes MODE_WORLD_READABLE and MODE_WORLD_WRITABLE are deprecated and do not work on newer devices. So I'd say you should rather write on the external storage to make contents available to other apps.

Note: as per documentation:

External storage: "It's world-readable, so files saved here may be read outside of your control."

Trinimon
  • 13,839
  • 9
  • 44
  • 60
  • I'm not trying to make it available to other apps! Both the writing and reading takes place in the same app. – Mousa Apr 30 '15 at 13:22
  • changing to `MODE_WORLD_READABLE` made it readable, but I wonder why `rw-------` is not enough when it's in the same app?! – Mousa Apr 30 '15 at 13:31
  • As far as I remember all apps run as their own user and the permissions you mentioned above allow only your app to write and read. The _MediaPlayer_ however, is part of another app running as another user that has no access rights per default. Once you extended the permission to `-rw-r--r--`, all users have the right to read (including the systems _MediaPlayer_) **p.s.:** take care with `MODE_WORLD_READABLE` - it might not always work – Trinimon Apr 30 '15 at 13:34
  • 1
    Yes, as the link Sameer provided, the main problem is in `MediaPlayer`. Since I don't like using deprecated things, I used Gabriella's approach to change permissions to prepare file for `MediaPlayer`. – Mousa Apr 30 '15 at 14:13
  • Gabriella's approach is just perfect for rooted phones ... :) – Trinimon Apr 30 '15 at 17:10
  • 1
    Yes, but since my app owns that file, I just execute `chmod` without `su`. – Mousa Apr 30 '15 at 17:19