문제

I have an app which should execute some root commands. SuperSU version is 1.04. Su version is 1.02. Android 4.1.1. Device is Samsung Galaxy S3 - rooted.

The problem is I cannot get a permission prompt from SuperSU. I've tried many things, but prompt never shows up.

For RootChecker basic, ADB and other apps it shows up. Here is my procedure - maybe I'm doing something wrong.

private static String runShellCommand(String command) {
    DataOutputStream os = null;
    Process process = null;
    try {
        String [] env = {"PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"}; 
        process = Runtime.getRuntime().exec("su", env, Environment.getExternalStorageDirectory() );
        os = new DataOutputStream(process.getOutputStream());

        InputStreamHandler err = new InputStreamHandler(process.getErrorStream(), false);
        InputStreamHandler out = new InputStreamHandler(process.getInputStream(), false);

        os.writeBytes(command + "\n");
        os.flush();

        os.writeBytes(EXIT);
        os.flush();
        os.close();
        Log.d(LOGTAG, "Waiting on: " + process.waitFor());

        String errOut = err.getOutput();
        String stdOut = out.getOutput(); 

        Log.d(LOGTAG, "Exit code: " + process.exitValue());
        Log.d(LOGTAG, command + " erroutput: [" + errOut + "]");
        Log.d(LOGTAG, command + " output: [" + stdOut + "]");
        if (errOut != null && !errOut.equals(""))
            return errOut;
        else if (stdOut != null&& !stdOut.equals(""))
            return stdOut;
        else 
            return null;
    } catch (Exception e) {
        Log.e(LOGTAG, "runShellCommand error: ", e);
        return null;
    } finally {
        try {
            if (os != null) {
                os.close();
            }
            if (process != null) {
                Log.d(LOGTAG, "Exit val: " + process.exitValue());
                process.destroy();
            }
        } catch (Exception ignored) {}
    }
}

InputStream handler is:

private static class InputStreamHandler extends Thread {
    private final InputStream stream;
    private final boolean devNull;
    StringBuffer output;

    public String getOutput() {
        return output.toString();
    }

    InputStreamHandler(InputStream stream, boolean devNull) {
        this.devNull = devNull;
        this.stream = stream;
        output = new StringBuffer();
        start();
    }

    @Override
    public void run() {
        try {
            if (devNull) {
                while (stream.read() != -1) {}
            } else {
                BufferedReader br = new BufferedReader(new InputStreamReader(stream));
                while (true) {
                    String line = br.readLine();
                    if (line == null) {
                        Log.d(LOGTAG, "Ended with reading!");
                        br.close();
                        return;
                    }
                    output.append(line);
                }
            }
        } catch (IOException ignored) {
            Log.e(LOGTAG, "Error", ignored);
        }
    }
}

Anyone have an idea why does it block so it doesn't show permission window? Thanks.

도움이 되었습니까?

해결책 2

I finally figured it out. The trick is to create a process (execute Runtime.getRuntime().exec("su");) separately in another thread. I'm not sure why this works, but it does. Similar way is used in RootTools. This has solved my problem.

다른 팁

I'm not exactly sure why this wouldn't work. The first thing that strikes me as odd is passing Environment.getExternalStorageDirectory() to exec. Maybe this (path) is not allowed (to execute from) ?

Why not simply use libsuperuser, written specifically to perform this very task ? It is open source, tiny, fully commented, has an example project, and even a document detailing the common problems you may encounter when trying to do this very operation.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top