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

Lon*_*uck 6 shell android root su

我需要我的应用程序以su编程方式执行一些命令(手机已植根).

使用adb完成后,命令可以正常工作.

例如: su -c "mkdir /sdcard/testdir"在/ sdcard中创建一个名为"testdir"的目录.

我打电话的时候:

    p = Runtime.getRuntime().exec("su -c \"mkdir /sdcard/testdir\"");
    p.waitFor();
Run Code Online (Sandbox Code Playgroud)

它只是继续前进,没有任何变化.

我试着阅读输入:

DataInputStream dis = new DataInputStream(p.getInputStream());
    while((temp = dis.readLine())!=null)
        Log.d(ctx.TAG,"shell:"+temp);
Run Code Online (Sandbox Code Playgroud)

但它没有任何报告(循环执行0次迭代).

有没有人曾经遇到过这个问题?怎么解决?毫无疑问,非su命令可以用这种方法以编程方式工作.

注意:我举了mkdir一个例子(我知道它不一定需要su).我需要执行很多不同的命令su

谢谢!

编辑:当我以su -c "id"编程方式调用时,输出uid = 0.

Lon*_*uck 14

我可以坚持几天的问题,当我鼓起勇气在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();
Run Code Online (Sandbox Code Playgroud)

不要忘记\n在你写入的每个命令的最后DataOutputStream,因为没有它,它将无法工作.

  • 它收到错误java.io.IOException:无法运行程序“ su”:error = 13,权限被拒绝 (2认同)

小智 6

你写道"你需要在su下执行各种命令".请注意,最着名的SuperSU根应用程序的开发人员Chainfire不鼓励使用"Runtime.exec()".

使用Runtime.getRuntime().exec("su -c [command]");是很诱人的,但你应该知道[command]应该是一个参数,因此可能需要引用.不幸的是,引用[command]参数以及将参数作为单独的变量传递给Runtime.exec()或ProcessBuilder都不能在所有Android版本中保持一致,因此应该完全避免使用此构造.这样做并非不可能 - 但是存在很高的问题风险.

请参阅如何SU文档.所以你可能想在这里遵循他的建议:

3.2.打电话

调用su的常用方法是避免上面列出的已知问题,方法是创建一个交互式shell和管道命令.这是通过调用Runtime.getRuntime().exec("su");来完成的,并从返回的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)
Run Code Online (Sandbox Code Playgroud)

SH变体用于非root shell,其中SU变体用于root shell.这些调用返回一个包含shell命令输出的List.如果没有输出,则列表为空,但不为空.如果发生错误,结果仅为null - 包括用户未授予您的应用程序访问权限.这些是阻止调用.

请注意,在调试编译中,所有shell STDIN/STDOUT/STDERR都将记录到logcat,如果从主线程调用,这些调用将(故意)使应用程序崩溃.其原因将在第4节中讨论.何时调用su.