2012-04-09 7 views
6

Por mi vida, no puedo obtener mi aplicación para obtener la respuesta de un proceso que llama a busybox desde dentro de su shell.Obtener resultados de los comandos de busybox dentro de la aplicación de Android

He intentado con tres métodos diferentes, así como he intentado una combinación de los tres para que funcione, pero nunca puedo obtener el resultado de nada usando busybox, solo el resto de los comandos. Para ser más específico, puedo conseguir que devuelva comandos como "ls/data" y "cat suchandsuch.file", pero cualquier cosa que comience con "busybox" (es decir, busybox mount, busybox gratis) simplemente no mostrará nada .

Este fue el método que tiene el más cercano para mí, este código funciona con "ls/datos", pero no "busybox libre"

Ésta sería ejecutar el comando (en su mayor parte), y el regreso una cadena vacía en lugar de un bucle sin fin desde la línea de entrada.

 Process p; 
     try { 
      p = Runtime.getRuntime().exec(new String[]{"su", "-c", "/system/bin/sh"}); 
     DataOutputStream stdin = new DataOutputStream(p.getOutputStream()); 
     stdin.writeBytes("ls /data\n"); 
     DataInputStream stdout = new DataInputStream(p.getInputStream()); 
     byte[] buffer = new byte[4096]; 
     int read = 0; 
     String out = new String(); 
     while(true){ 
      read = stdout.read(buffer); 
      out += new String(buffer, 0, read); 
      if(read<4096){ 
       break; 
      } 
     } 
     Toast.makeText(getApplicationContext(), out, Toast.LENGTH_SHORT).show(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

El pan cerca de la parte inferior muestra todo, desde "ls/datos", pero cuando se cambia a cualquier cosa por busybox, su blanco o nulo.

También he intentado ambos, pero ninguno de ellos funcionó. (Les estaba pasando el proceso después de que se ejecutó el comando).

Ambos elementos siempre darán como resultado la congelación de la aplicación correcta cuando presiona el botón para los métodos.

String termReader(Process process){ 
    BufferedReader reader = new BufferedReader(
     new InputStreamReader(process.getInputStream())); 
    try { 

    int i; 
    char[] buffer = new char[4096]; 
    StringBuffer output = new StringBuffer(); 
    while ((i = reader.read(buffer)) > 0) output.append(buffer, 0, i); 
    reader.close(); 
    return output.toString(); 
    } catch (IOException e) { 
    e.printStackTrace(); 
    return e.getMessage(); 
    } 
} 



String processReader(Process process){ 
    InputStream stdout = process.getInputStream(); 
    byte[] buffer = new byte[1024]; 
    int read; 
    String out = new String(); 
    while(true){ 
     try { 
      read = stdout.read(buffer); 
     out += new String(buffer, 0, read); 
     if(read<1024){ 
      break; 
     } 
     } catch (IOException e) { 
      e.printStackTrace(); 

     } 
    } 
    return out; 
} 

Theres ninguna trazas de la pila para trabajar, así que estoy empezando a tener un poco perplejo.

Editado con el código propuesto a continuación, uhm, a continuación: D Lo cambié un poco para que sea una operación de un clic para facilitar la solución de problemas y las pruebas.

Esto también se congela cuando trata de leer el inputstream, y si llamo a stdin.writeBytes ("exit \ n") antes de intentar leer la secuencia, me da la respuesta en blanco al cerrar el terminal, si lo llamo después, bucles interminablemente.

 void Run() { 
       String command = "busybox traceroute\n"; 



     StringBuffer theRun = null; 
     try { 
      Process process = Runtime.getRuntime().exec("su"); 
      DataOutputStream stdin = new DataOutputStream(process.getOutputStream()); 
      stdin.writeBytes(command); 
      BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream())); 
      int read; 
      char[] buffer = new char[4096]; 
      StringBuffer output = new StringBuffer(); 
      while ((read = reader.read(buffer)) > 0) { 
       theRun = output.append(buffer, 0, read); 
      } 
      reader.close(); 
      process.waitFor(); 

     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } catch (InterruptedException e) { 
      throw new RuntimeException(e); 
     } 
     Toast.makeText(getApplicationContext(), theRun, Toast.LENGTH_SHORT).show(); 
    } 

Parece que su saltarse la primera línea (la línea de información busybox se obtiene cada vez que se invoca el comando) y no para controlar el resto de los datos. He intentado todas las variaciones que se me ocurre para conseguir este funcionamiento correcto:/

Si alguien tiene una idea de esto, yo estaría en gran medida apreciative :)

Respuesta

1

he encontrado una especie de una solución para este .

En primer lugar, ejecutar comandos vinculados a busybox en mi caso nunca devolvería su salida a través de su InputStream, sin importar el método que probé (e intenté con ALOT lol).

Esto es lo que descubrí que podía hacer. Es un poco tedioso, y no te da el resultado completo, pero si quieres algo en que depender si un comando se activó correctamente (en mi caso, mi aplicación no funcionaría bien si no pudiera comparar cómo funcionaba todo).)

no puede obtener la entrada del proceso, pero se puede obtener el valor de salida si se trabaja bien :) esto funciona para cualquier cosa que imposible darle una respuesta compleja (como el uso de gato en un archivo grande)

la diferencia entre los dos es fácil de encontrar, por ejemplo:

command = "cat /sys" // works, exits with 1 

command = "cat /init.rc" doesnt work, exits with 0 

así es como lo configuro para trabajar fácilmente. Ejecutar los comandos de forma normal utilizando el método proporcionado por MasterJB:.

  Process p; 
     try { 
      p = Runtime.getRuntime().exec(new String[]{"su", "-c", "/system/bin/sh"}); 
     DataOutputStream stdin = new DataOutputStream(p.getOutputStream()); 
     stdin.writeBytes(command); 
     stdin.writeBytes("echo $?\n"); 

     DataInputStream stdout = new DataInputStream(p.getInputStream()); 
     byte[] buffer = new byte[4096]; 
     int read = 0; 
     String out = new String(); 
     while(true){ 
      read = stdout.read(buffer); 
      out += new String(buffer, 0, read); 
      if(read<4096){ 
       break; 
      } 

        // here is where you catch the error value 

           int len = out.length(); 
     char suExitValue = out.charAt(len-2); 
     Toast.makeText(getApplicationContext(), String.valueOf(suExitValue), Toast.LENGTH_SHORT).show(); 


        return0or1(Integer.valueOf(suExitValue), command); // 0 or 1 Method 

        // end catching exit value        

     } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

También me pareció más fácil de hacer que un método "0 ó 1" para devolver lo que pasó, en este ejemplo, su despedido como una tostada. También puede probar si el carácter es un número entero, ya que algunos comandos no dan ningún valor de salida (extraño, lo sé. Una instancia es ls/sys, esto devuelve un valor de salida en blanco cuando se ejecuta a través de un terminal su.)

String return0or1 (int returnValue, String command){ 
    String message = command + " - Cannot get return value."; 

    if (returnValue == 0){ 
     message = command + " - successful."; 
     return message; 
    } 
    if (returnValue == 1){ 
     message = command + " - failed."; 
     return message; 
    } 
    return message; 
} 

con un poco de investigación que puede coincidir con casi cualquier valor de salida con las respuestas correctas, sólo tengo que capturarlos derecha :)

estos métodos devuelven solo si el comando corrió (0), pero si obtiene un código de salida de doble o triple, el último dígito puede ser 0 cuando falla (es decir, cuando el valor de salida es 10), por lo que esto funcionará en la mayoría de los casos, pero debe ampliarse para obtener valores dobles y triples.

3

Aquí hay una solución rápida ... Es una clase de utilidad que he creado solo para esto. Puede usar el shell nativo, un shell raíz si el dispositivo está rooteado o establecer un shell personalizado. Aqui tienes.

https://github.com/jjNford/android-shell

+0

Esto es oro! ¡Gracias! –

Cuestiones relacionadas