Ejecutar comando de shell desde Android

Estoy tratando de ejecutar este comando desde el terminal del emulador de aplicaciones (puedes encontrarlo en google play) en esta aplicación escribo su y presiono enter , así que escribo:

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

y presione nuevamente para ingresar e iniciar la grabación de la pantalla con la nueva función de android kitkat.

entonces, bash ejecutar el mismo código desde Java usando esto:

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

Pero no funciona porque el archivo no está creado. obviamente me estoy ejecutando en un dispositivo rooteado con Android Kitkat instalado. ¿Dónde está el problema? ¿Cómo puedo resolver? porque desde el emulador de terminal funciona y en Java no?

Debería tomar la entrada estándar del proceso su recién iniciado y anotar allí el comando; de lo contrario, está ejecutando los comandos con el UID actual.

Pruebe algo como esto:

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

Una modificación del código por @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(); } } 

(Le invitamos a encontrar un lugar mejor para outputStream.close () )

Ejemplo de uso:

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

Actualización: para obtener el resultado (la salida a stdout), use:

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

La utilidad para cerrar silenciosamente un número de objetos cerrables ( Soсket puede no ser Cerrar ) es:

 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; 

Ejemplo para copiar archivo:

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