Я пытаюсь создать приложение, которое позволяет мне переключать регуляторы масштабирования моего телефона (да, я рутирован). После долгих поисков я обнаружил, что обычно от меня требуется запускать команду с 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
Когда я запускаю приложение, оно либо зависает, либо ничего не делает. Не уверен, что делаю не так? Любая помощь очень ценится!
Это код, который я использую для своих приложений:
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 и т. д.).
@NicholasKoh да
Спасибо за вашу помощь! Еще одна вещь: правильно ли сказать, что DataOutputStream обычно предназначен для ввода команд терминала (для моего случая использования), а DataInputStream - для получения результатов с терминала (если есть)? Или можно использовать что-то подобное для результатов? "Читатель BufferedReader = новый BufferedReader (новый InputStreamReader (process.getInputStream ()));"