我需要我的应用程序以编程方式执行一些su
命令(手机已植根)。
使用adb完成后,命令可以正常工作。
例如:
su -c "mkdir /sdcard/testdir"
在/ sdcard中创建一个名为“testdir”的目录。
我打电话的时候:
p = Runtime.getRuntime().exec("su -c \"mkdir /sdcard/testdir\"");
p.waitFor();
它继续前进,没有任何变化。
我尝试阅读输入:
DataInputStream dis = new DataInputStream(p.getInputStream());
while((temp = dis.readLine())!=null)
Log.d(ctx.TAG,"shell:"+temp);
但它没有报告任何内容(循环执行0次迭代)。
之前有没有人遇到过这个问题?怎么解决? 毫无疑问,非su命令可以用这种方法以编程方式工作。
注意:我以mkdir
为例(我知道它不一定需要su)。我需要在su
谢谢!
编辑:当我以编程方式调用su -c "id"
时,输出uid = 0.
答案 0 :(得分:13)
我可以坚持几天的问题,当我鼓起勇气在StackOverflow上询问它时,它会在几分钟内解决。
修复方法是:
p=Runtime.getRuntime().exec("su");
DataOutputStream dos = new DataOutputStream(p.getOutputStream());
dos.writeBytes("mkdir /sdcard/testdir\n");
dos.writeBytes("exit\n");
dos.flush();
dos.close();
p.waitFor();
在您写入\n
的每个命令的末尾,不要忘记DataOutputStream
,因为没有它,它将无效。
答案 1 :(得分:6)
你写道,你需要在su"下执行各种命令。注意使用" Runtime.exec()"最着名的SuperSU根应用程序的开发者Chainfire不鼓励。
很有诱惑力使用Runtime.getRuntime()。exec(" su -c [command]");但你应该知道[command]应该是一个参数,因此可能需要引用。不幸的是,引用[command]参数以及将参数作为单独的变量传递给Runtime.exec()或ProcessBuilder都不能在所有Android版本中保持一致,因此应该完全避免使用此构造。这样做并非不可能 - 但是存在高风险的问题。
请参阅How to SU文件。所以你可能想在这里遵循他的建议:
<强> 3.2。拨打电话
调用su的常用方法可以避免上面列出的已知问题,方法是创建一个交互式shell和管道命令。这是通过调用Runtime.getRuntime()。exec(&#34; su&#34;);以及从返回的Process对象检索输入和输出流来完成的。这样做是一段相当简单的代码,但包括调试日志并检查它在这里重现有点长。
核心代码位于此处:[libsuperuser :: Shell.java @ GitHub]。 Shell.run()是一个运行shell代码的通用调用,下面更具体的(静态)实用函数是你可能最终使用的函数:
List<String> Shell.SH.run(String command)
List<String> Shell.SH.run(List<String> commands)
List<String> Shell.SH.run(String[] commands)
List<String> Shell.SU.run(String command)
List<String> Shell.SU.run(List<String> commands)
List<String> Shell.SU.run(String[] commands)
SH变体用于非root shell,其中SU变体用于root shell。这些调用返回一个包含shell命令输出的List。如果没有输出,则列表为空,但不为空。如果发生错误,结果仅为null - 包括用户未授予您的应用程序访问权限。这些是阻止电话。
请注意,在调试编译中,所有shell STDIN / STDOUT / STDERR都将记录到logcat,如果从主线程调用,这些调用将(故意)使应用程序崩溃。其原因将在第4节中讨论。何时调用su。
答案 2 :(得分:1)
如果您使用双引号,它将起作用:
su -c ""command with args""
答案 3 :(得分:-1)
您可能在主线程中调用Runtime.getRuntime().exec()
,p.waitFor()
使主线程等待直到执行。尝试调用另一个线程,如下面的代码片段。
new Thread(){
@override
public void run(){
p = Runtime.getRuntime().exec("su -c \"mkdir /sdcard/testdir\"");
p.waitFor();
}.start();
}