0

I have been trying many things but I still cannot find a proper way to check if my app has root access. This is what I've tried:

private boolean isRootGranted() {
    Process p;
    BufferedReader reader = null;
    String line;

    try {
        p = Runtime.getRuntime().exec("su");
        reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        while( (line = reader.readLine()) != null) {
            System.out.println(line);
        }

        int result;
        try {
            result = p.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
            Toast.makeText(this, "You need to grant root access", Toast.LENGTH_SHORT).show();
            return false;
        }

        if(result != 0) {
            Toast.makeText(this, "You need to grant root access", Toast.LENGTH_SHORT).show();
            return false;
        }

        return true;
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "Your device is not rooted", Toast.LENGTH_SHORT).show();
        return false;
    } finally {
        try {
            if(reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Above code works perfectly if the device doesn't have root or the root is denied. However, every time the root is granted, it got stuck on the while loop. If I remove the while loop, it got stuck on p.waitFor()

EDIT I find out that su command doesn't produce any output. But I don't know why it still stuck on waitFor() if no output/error produces.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • Why do you have the while loop at all? It isn't doing anything, just printing to a log. Get rid of it. – Gabe Sechan Jun 01 '19 at 04:58
  • I read somewhere that "some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock." So, I need to handle the streams to an external process by doing the while loop. Even though I removed the loop, it still stuck on waitFor(). – Bernhard Josephus Jun 01 '19 at 05:41
  • There's not going to be much writing to the stream. You're executing su with no parameters- its going to write a very small message and end. (and if it doesn't end, that would be an infinite loop). Its not needed – Gabe Sechan Jun 01 '19 at 05:46
  • Okay, let say I have removed the while loop. Now, how do I get rid of waitFor() stuck? – Bernhard Josephus Jun 01 '19 at 05:54

1 Answers1

1

To check if your app has superuser rights, you simply can try to access the root directory. This is how I solved this problem:
The following method checks if it can list the files of the root directory. If the shell command (cd / && ls) returns an empty String, your app has no root access and the method returns false.

public boolean hasRootAccess() {
        try {
            java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(new String[]{"/system/bin/su","-c","cd / && ls"}).getInputStream()).useDelimiter("\\A");
            return !(s.hasNext() ? s.next() : "").equals("");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
}
Lexip
  • 11
  • 1