Чтение выходных данных процесса суперпользователя в Android

#android

#Android

Вопрос:

Я пытаюсь периодически запускать команду оболочки с помощью суперпользователя (su) следующим образом:

сначала я получаю процесс su:

 Process p = Runtime.getRuntime().exec("su");
  

затем, периодически я запускаю:

 p.getOutputStream().write("some shell command".getBytes());
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = r.readLine()) != null) //Process output line
  

эта проблема заключается в том, что r.readLine() блокируется и никогда не возвращается. только если я создам новый процесс su и добавлю p.getOutputStream().close() перед чтением выходных данных, код завершится успешно.

есть ли способ использовать один процесс su для выдачи команд оболочки?

Комментарии:

1. Вы используете корневое устройство или эмулятор? Я спрашиваю об этом, потому что есть только несколько устройств, которые позволяют вам выполнять команды root

2. Я использую корневое устройство. Выполнение каждой команды отдельно работает нормально, но я получаю много тостов su, я хочу запускать команды из одного экземпляра процесса su…

Ответ №1:

Черт возьми, я только что столкнулся с той же проблемой, и, похоже, я решил ее, проверив r.ready() BufferedReader. Если больше нет строк для чтения из выходных данных процесса, r.ready() возвращает false. Я не знаю, насколько это будет надежно в разных версиях ОС, но это работает на 2.3.

Редактировать: кроме того, перед началом чтения выходных данных убедитесь, что вы немного спите (скажем, 200 мс), чтобы весь вывод вашей команды попал в буфер.

Ответ №2:

Вы должны определить процесс с помощью ProcessBuilder Try:

 Process p = new ProcessBuilder()
    .command("su")
    .redirectErrorStream(true)
        .start();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (inputReader.ready() amp;amp; (line = inputReader.readLine()) != null)
            {
                System.out.println(line);
            }
  

Если вы не заинтересованы в различении потоков out и err, используйте redirectErrorStream(true) для объединения двух потоков. Это упрощает чтение кода и позволяет избежать блокировки целевого процесса. Ссылка