2014-01-05 33 views
30

我試圖從應用程序模擬器終端執行此命令shell命令(你可以找到它在谷歌扮演)在這個程序我寫su並按進入,這麼寫:執行從Android的

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

並再次按下輸入並使用android kitkat的新功能開始錄製屏幕。

所以,我嘗試使用這種從Java執行相同的代碼:

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

但是因爲沒有創建文件不起作用。顯然,我在安裝了android kitkat的rooted設備上運行。哪裏有問題?我怎麼解決?因爲從終端仿真器的工作和Java不是?

+0

重複http://stackoverflow.com/questions/20855502/execute-a-shell-command-programmatically-why-it-doesnt-work? – fadden

回答

52

您應該抓取剛剛啓動的su進程的標準輸入並在其中寫下命令,否則您正在使用當前的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); 
} 
+3

某些版本的'su'將在命令行中引用參數,因此您可以'exec(「su -c screenrecord /sdcard/foo.mp4」)'。 – fadden

+4

是否可以在沒有root權限的情況下進行錄製? –

+0

@carlo是否有可能以root權限運行這樣的命令 –

22

代碼由@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()

使用示例:

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

更新: 要得到的結果(輸出到stdout),用途:

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"); 
} 

效用默默地關閉一批Closeables的(Soсket may be no Closeable)是:

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); 
      } 
     } 
    } 
} 
} 
5
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; 
1

複製文件示例:

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(); 
    } 
}