سؤال

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