4

I know it is possible to change the permission mode of a file using:

Runtime.getRuntime().exec( "chmod 777 myfile" );.

This example sets the permission bits to 777. Is it possible to set the permission bits to 777 programmatically using Java? Can this be done to every file?

cytinus
  • 5,467
  • 8
  • 36
  • 47
Sathish Sathish
  • 2,251
  • 3
  • 20
  • 21
  • 1
    Maybe you can find some idea's in this post ? : http://stackoverflow.com/questions/664432/how-do-i-programmatically-change-file-permissions – Silmarillium Jul 10 '12 at 07:04
  • Internally Android uses the `android.os.FileUtils` which, as usual, is hidden from the SDK. You can however access it using reflection if you do not wish to call `#exec(..)`. – Jens Jul 10 '12 at 07:17

4 Answers4

9

Using chmod in Android

Java doesn't have native support for platform dependent operations like chmod. However, Android provides utilities for some of these operations via android.os.FileUtils. The FileUtils class is not part of the public SDK and is therefore not supported. So, use this at your own risk:

public int chmod(File path, int mode) throws Exception {
 Class fileUtils = Class.forName("android.os.FileUtils");
Method setPermissions =
  fileUtils.getMethod("setPermissions", String.class, int.class, int.class, int.class);
return (Integer) setPermissions.invoke(null, path.getAbsolutePath(), mode, -1, -1);
}

...
chmod("/foo/bar/baz", 0755);
...

Reference : http://www.damonkohler.com/2010/05/using-chmod-in-android.html?showComment=1341900716400#c4186506545056003185

Ashraf
  • 3,114
  • 3
  • 23
  • 22
  • Not only is it not part of the public SDK API, but it is apparently **removed** in devices with versions higher than 4.2.2, according to: http://stackoverflow.com/questions/20858972/getting-java-lang-nosuchmethoderror-android-os-fileutils-getfatvolumeid-in-4-2 – Jesse W at Z - Given up on SE Oct 14 '14 at 17:57
  • this will not work for Android 6.0 (API 23) and above – kc_dev Aug 14 '21 at 21:08
1

Android make it difficult to interact with other applications and their data except through Intents. Intents won't work for permissions because you're dependent on the application receiving the Intent to do/provide what you want; they probably weren't designed to tell anybody their files' permissions. There are ways around it, but only when the applications are desgned to operate in the same JVM. So each application can only change it's file. for more detail in file permission see http://docs.oracle.com/javase/1.4.2/docs/guide/security/permissions.html

Pooya
  • 4,385
  • 6
  • 45
  • 73
1

As commented previously, android.os.FileUtils has changed and the solution posted by Ashraf no longer works. The following method should work on all versions of Android (although it does use reflection and if a manufacturer made major changes this may not work).

public static void chmod(String path, int mode) throws Exception {
    Class<?> libcore = Class.forName("libcore.io.Libcore");
    Field field = libcore.getDeclaredField("os");
    if (!field.isAccessible()) {
        field.setAccessible(true);
    }
    Object os = field.get(field);
    Method chmod = os.getClass().getMethod("chmod", String.class, int.class);
    chmod.invoke(os, path, mode);
}

Obviously you will need to own the file to make any permission changes.

Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
0

Here is a solution using Apache Commons.IO FileUtils, and the appropriate methods on File objects.

for (File f : FileUtils.listFilesAndDirs(new File('/some/path'), TrueFileFilter.TRUE, TrueFileFilter.TRUE)) {
    if (!f.setReadable(true, false)) { 
        throw new IOException(String.format("Failed to setReadable for all on %s", f));
    }
    if (!f.setWritable(true, false)) {
        throw new IOException(String.format("Failed to setWritable for all on %s", f));
    }
    if (!f.setExecutable(true, false)) { 
        throw new IOException(String.format("Failed to setExecutable for all on %s", f));
    }
}

This is the equivalent of chmod -R 0777 /some/path. Adjust the set{Read,Writ,Execut}able calls to implement other modes. (I'll happily update this answer if someone posts appropriate code to do this.)