从android执行shell命令

我试图从应用程序模拟器terminal执行这个命令(你可以在谷歌播放中find它)在这个应用程序中我写su然后按回车键,所以写:

screenrecord --time-limit 10 /sdcard/MyVideo.mp4

再按一下进入 ,使用android kitkat的新function开始录制画面。

所以,我尝试执行相同的代码从Java使用这个:

 Process su = Runtime.getRuntime().exec("su"); Process execute = Runtime.getRuntime().exec("screenrecord --time-limit 10 /sdcard/MyVideo.mp4"); 

但不要工作,因为该文件没有创build。 显然,我运行在安装了android kitkat的rooted设备上。 哪里有问题? 我怎么解决? 因为从terminal模拟器的工作和在Java中不?

Solutions Collecting From Web of "从android执行shell命令"

您应该抓取刚启动的su进程的标准input,并在那里写下命令,否则您正在使用当前UID运行命令。

尝试这样的事情:

 try{ Process su = Runtime.getRuntime().exec("su"); DataOutputStream outputStream = new DataOutputStream(su.getOutputStream()); outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n"); outputStream.flush(); outputStream.writeBytes("exit\n"); outputStream.flush(); su.waitFor(); }catch(IOException e){ throw new Exception(e); }catch(InterruptedException e){ throw new Exception(e); } 

@CarloCannas对代码的修改:

 public static void sudo(String...strings) { try{ Process su = Runtime.getRuntime().exec("su"); DataOutputStream outputStream = new DataOutputStream(su.getOutputStream()); for (String s : strings) { outputStream.writeBytes(s+"\n"); outputStream.flush(); } outputStream.writeBytes("exit\n"); outputStream.flush(); try { su.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } outputStream.close(); }catch(IOException e){ e.printStackTrace(); } } 

(欢迎您为outputStream.close()find一个更好的地方)

用法示例:

 private static void suMkdirs(String path) { if (!new File(path).isDirectory()) { sudo("mkdir -p "+path); } } 

更新:要得到结果(输出到标准输出),使用:

 public static String sudoForResult(String...strings) { String res = ""; DataOutputStream outputStream = null; InputStream response = null; try{ Process su = Runtime.getRuntime().exec("su"); outputStream = new DataOutputStream(su.getOutputStream()); response = su.getInputStream(); for (String s : strings) { outputStream.writeBytes(s+"\n"); outputStream.flush(); } outputStream.writeBytes("exit\n"); outputStream.flush(); try { su.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } res = readFully(response); } catch (IOException e){ e.printStackTrace(); } finally { Closer.closeSilently(outputStream, response); } return res; } public static String readFully(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = 0; while ((length = is.read(buffer)) != -1) { baos.write(buffer, 0, length); } return baos.toString("UTF-8"); } 

实用程序以静默方式closures一些Closeables( Soekket可能是不可closures的 )是:

 public class Closer { // closeAll() public static void closeSilently(Object... xs) { // Note: on Android API levels prior to 19 Socket does not implement Closeable for (Object x : xs) { if (x != null) { try { Log.d("closing: "+x); if (x instanceof Closeable) { ((Closeable)x).close(); } else if (x instanceof Socket) { ((Socket)x).close(); } else if (x instanceof DatagramSocket) { ((DatagramSocket)x).close(); } else { Log.d("cannot close: "+x); throw new RuntimeException("cannot close "+x); } } catch (Throwable e) { Log.x(e); } } } } } 
 Process p; StringBuffer output = new StringBuffer(); try { p = Runtime.getRuntime().exec(params[0]); BufferedReader reader = new BufferedReader( new InputStreamReader(p.getInputStream())); String line = ""; while ((line = reader.readLine()) != null) { output.append(line + "\n"); p.waitFor(); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } String response = output.toString(); return response; 

示例复制文件:

 void copyFile_dd(){ try { Process su; su = Runtime.getRuntime().exec("su"); String cmd = "dd if=/mnt/sdcard/test.dat of=/mnt/sdcard/test1.dat \n"+ "exit\n"; su.getOutputStream().write(cmd.getBytes()); if ((su.waitFor() != 0)) { throw new SecurityException(); } } catch (Exception e) { e.printStackTrace(); //throw new SecurityException(); } }