How to check if my app has been granted root access?
Asked Answered
C

2

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.

Chian answered 1/6, 2019 at 4:34 Comment(4)
Why do you have the while loop at all? It isn't doing anything, just printing to a log. Get rid of it.Gentlemanly
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().Chian
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 neededGentlemanly
Okay, let say I have removed the while loop. Now, how do I get rid of waitFor() stuck?Chian
L
2

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;
}
Luzon answered 10/2, 2021 at 19:35 Comment(0)
H
0

After searching for a solution to test if SuperUser Access granted or not, only Lexip's above solution with Scanner works fine.

To complete his response:

    boolean isRooted = false;
    boolean isRootGranted = false;
    try {
        Process process = Runtime.getRuntime().exec("su -c ls");     // Ask for su and list
        Scanner scanner = new Scanner(process.getInputStream()).useDelimiter("\\A");
        if (scanner.hasNext()) isRootGranted = true;
        scanner.close();
        process.waitFor();
        process.getInputStream().close();
        process.destroy();
        isRooted = true;
        if (isRootGranted) Toast.makeText(MainActivity.this, "ROOT granted", Toast.LENGTH_SHORT).show();
        else Toast.makeText(MainActivity.this, "ROOT not granted", Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        isRooted = false;
        Toast.makeText(MainActivity.this, "ERROR #SU AUTORISATION\nPHONE NON ROOTED", Toast.LENGTH_SHORT).show();
    }

isRooted = true on a rooted phone, and false if not.

isRootGranted = true if superUser Access is granted, and false if not.

Regards.

Heartwarming answered 18/12, 2023 at 5:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.