Запуск команд терминала в Android Studio

Я пытаюсь создать приложение, которое позволяет мне переключать регуляторы масштабирования моего телефона (да, я рутирован). После долгих поисков я обнаружил, что обычно от меня требуется запускать команду с process = Runtime.getRuntime().exec(cmd);.

Однако после многих попыток приложение не реагирует должным образом. Это мой код на данный момент.

    String RunCommand(String cmd) {
    StringBuffer cmdOut = new StringBuffer();
    Process process;
    try{
        process = Runtime.getRuntime().exec(cmd);
        InputStreamReader r = new InputStreamReader(process.getInputStream());
        BufferedReader bufReader = new BufferedReader(r);
        char[] buf = new char[4096];
        int nRead = 0;
        while ((nRead = bufReader.read(buf)) > 0){
            cmdOut.append(buf, 0, nRead);
        }
        bufReader.close();
        try {
            process.waitFor();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }catch (IOException e) {
        e.printStackTrace();
    }
    return cmdOut.toString();
}

Фактически, мне не нужен выходной файл, так как команды, которые я выполняю, действительно не нуждаются в выходных данных. т.е. echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

Когда я запускаю приложение, оно либо зависает, либо ничего не делает. Не уверен, что делаю не так? Любая помощь очень ценится!

1
0
1 277
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это код, который я использую для своих приложений:

fun sudo(vararg strings: String) {
    try {
        val su = Runtime.getRuntime().exec("su")
        val outputStream = DataOutputStream(su.outputStream)

        for (s in strings) {
            outputStream.writeBytes(s + "\n")
            outputStream.flush()
        }

        outputStream.writeBytes("exit\n")
        outputStream.flush()
        try {
            su.waitFor()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }

        outputStream.close()
    } catch (e: IOException) {
        e.printStackTrace()
    }

}

Он на Kotlin, но его легко преобразовать в Java.

Я считаю, что ключевой частью является запуск вашего нового процесса (exec()) с su. Затем функция записывает команды, которые вы отправляете, в OutputStream, поэтому он запускает их в процессе su.

Если ваше приложение зависает, убедитесь, что вы предоставляете ему root-доступ с помощью любого используемого вами менеджера (Magisk, SuperSU и т. д.).

Спасибо за вашу помощь! Еще одна вещь: правильно ли сказать, что DataOutputStream обычно предназначен для ввода команд терминала (для моего случая использования), а DataInputStream - для получения результатов с терминала (если есть)? Или можно использовать что-то подобное для результатов? "Читатель BufferedReader = новый BufferedReader (новый InputStreamReader (process.getInputStream ()));"

Nicholas Koh 09.09.2018 10:31

@NicholasKoh да

TheWanderer 09.09.2018 12:24

Другие вопросы по теме