Android以编程方式执行su命令不起作用

时间:2015-04-20 14:04:32

标签: android shell root su

我需要我的应用程序以编程方式执行一些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.

4 个答案:

答案 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();

}