Search code examples
androidlinuxmedia-playerchmod

How to execute a chmod in Android - API 8?


I have a problem running my application which plays mp3, on Android 2.3. These mp3 are downloaded from a remote server to /data/data/com.my.package.name/, and the default file permissions are -rw-------.

Unlike on post HONEYCOMB devices (According to my tests), media player refuses to read mp3 if their file permissions are not -rw-rw-rw-.

I obviously verified that if I set files permissions to 666 with the adb shell, then the media player successfully read it.

So, after some researches on the net, I tried to implement the following code, just after writing the file:

String chmodString = "chmod 666 " + getActivity().getApplicationContext().getFilesDir().getParentFile().getPath() +"/" + fileName;
Process sh = Runtime.getRuntime().exec("su", null, new File("/system/bin/"));
OutputStream osChgPerms = sh.getOutputStream();
try {
    osChgPerms.write((chmodString).getBytes("ASCII"));
    osChgPerms.flush();
    osChgPerms.close();
    sh.waitFor();
} catch (InterruptedException e) {
    Log.d("2ndGuide", "InterruptedException." + e);
} catch(IOException e) {
    Log.d("2ndGuide", "IO Exception." + e);
}

This code is executed in a fragment but I don't think that changes anything.

Unfortunately, if this code works on post HONEYCOMB devices, where it's not useful,

osChgPerms.write((chmodString).getBytes("ASCII")); 

Throws an IOException: broken pipe on Android 2.3, where I really need it.

In fact, I don't really know if the problem comes from the chmod or from the way to execute it.

Any solution to get it working or, to get the media player working on pre HONEYCOMB without changing file permissions?


Solution

  • Very good question, I ran in this problem a while back!

    Using Java + Android(User must have chmod):

    Folders:

    Runtime.getRuntime().exec("chmod -R 777 " + FOLDERNAME);
    

    Files:

    Runtime.getRuntime().exec("chmod 777 " + FILENAME);
    

    Problem: What if they do not have the "chmod" binary? You must download and include it in your application or assets.

    Using Android NDK + JNI(User does not need chmod but needs compiled ndk libs):

    /**
     * Change file permissions. Eg. chmod 777 FILE.
     * @param e Java environment.
     * @param c Java class.
     * @param file Path to file.
     * @param mode Permissions for the file.
     */
    static jint executeCommand(JNIEnv *e, jclass __attribute__((__unused__))c, jstring file, jstring mode) {
        return (chmod(e->GetStringUTFChars(file, 0), strtol(e->GetStringUTFChars(mode, 0), 0, 8)));
    }
    

    Problem: Make sure to compile NDK with APP_ABI := all for all devices

    For Java(7+) + Android API 9+(User does not need chmod or libs):

    /**
     * Change files to "0777"
     * @param path Path to file
     */
    public static void changeFilePermission(final String path) {
        final File file = new File(path);
        file.setReadable(true, false);
        file.setExecutable(true, false);
        file.setWritable(true, false);
    }
    

    Problem: Your minSDK must be 9!