На всю жизнь я не могу заставить свое приложение получать ответ от процесса, вызывающего busybox из оболочки su.
Я пробовал три разных метода, а также пробовал комбинацию из трех, чтобы заставить его работать, но я никогда не могу получить результат ни от чего, используя busybox, только остальные команды.
Чтобы быть более конкретным, я могу заставить его возвращать такие команды, как «ls /data» и «cat такой-то и такой-то.файл», но все, что начинается с «busybox» (т.
Этот метод оказался наиболее близким для меня, этот код работает с "ls /data", но не с "busybox free"
Этот метод запускал команду (по большей части) и возвращал пустой строка вместо бесконечного цикла из входного потока.
Process p;
try {
p = Runtime.getRuntime().exec(new String[]{"su", "-c", "/system/bin/sh"});
DataOutputStream stdin = new DataOutputStream(p.getOutputStream());
stdin.writeBytes("ls /data\n");
DataInputStream stdout = new DataInputStream(p.getInputStream());
byte[] buffer = new byte[4096];
int read = 0;
String out = new String();
while(true){
read = stdout.read(buffer);
out += new String(buffer, 0, read);
if(read<4096){
break;
}
}
Toast.makeText(getApplicationContext(), out, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
В нижней части всплывающего уведомления отображается все, начиная с «ls /data», но при изменении на что-либо для busybox оно становится пустым или нулевым.
Я пробовал и то, и другое, но ни одно из них не сработало. (Я передал им процесс после запуска команды.)
И то, и другое всегда приводило к зависанию приложения сразу после нажатия кнопки методов.
String termReader(Process process){
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
try {
int i;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((i = reader.read(buffer)) > 0) output.append(buffer, 0, i);
reader.close();
return output.toString();
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
}
String processReader(Process process){
InputStream stdout = process.getInputStream();
byte[] buffer = new byte[1024];
int read;
String out = new String();
while(true){
try {
read = stdout.read(buffer);
out += new String(buffer, 0, read);
if(read<1024){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return out;
}
Нет трассировки стека для работы, так что я начинаю немного запутываться.
Отредактировано с кодом, предложенным ниже, гм, ниже :D Я немного изменил его, чтобы его можно было запускать одним щелчком мыши для облегчения устранения неполадок и тестирования.
Это также зависает, когда он пытается прочитать входной поток, и если я вызываю stdin.writeBytes("exit\n") перед попыткой прочитать поток, это дает мне пустой ответ от закрытия терминала, если я вызываю его после , он бесконечно зацикливается.
void Run() {
String command = "busybox traceroute\n";
StringBuffer theRun = null;
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream stdin = new DataOutputStream(process.getOutputStream());
stdin.writeBytes(command);
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
theRun = output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Toast.makeText(getApplicationContext(), theRun, Toast.LENGTH_SHORT).show();
}
Похоже, что он пропускает первую строку (информационная строка busybox, которую вы получаете каждый раз, когда запускаете команду) и не перехватывает остальные данные. Я перепробовал все возможные варианты, чтобы заставить это работать правильно :/
Если у кого-нибудь есть понимание этого, я был бы очень признателен :)