📜 ⬆️ ⬇️

Interaction of Java and Shell-scripts in Android

It so happened that in my current project it was necessary to implement the execution of shell scripts straight from the code.

In order to get up to date, I advise you to read this article: Shell-scripting in the Android environment

The Shell language is very well described in it, however, besides the scripts themselves, I had to execute Java methods.

In the development process was used the image of Android_x86. However, you can use a rooted phone (superuser is required).
')
The Java scripts themselves are fairly simple:
/** *    shell   . * * @param command shell . */ public void runCommand(final String command) { //    ,     new Thread(new Runnable() { public void run() { OutputStream out = null; InputStream in = null; try { //      Process child = Runtime.getRuntime().exec(command); //     out = child.getOutputStream(); in = child.getInputStream(); //   -  BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); String line; String result = ""; while ((line = bufferedReader.readLine()) != null) result += line; // ,    handleBashCommandsResult(result); } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } } }).start(); } 

In Android_x86, you can send scripts immediately to the process, and they will be executed. If you use the phone, then this line:
 Process child = Runtime.getRuntime().exec(command); 

need to be replaced by these:
 Process child = Runtime.getRuntime().exec(new String[] { "su", "-c", "system/bin/sh" }); DataOutputStream stdin = new DataOutputStream(child.getOutputStream()); // stdin.writeBytes(command); 

I do not know how this can be explained, but on the phone you need to run a command shell before executing the scripts. The rest is all the same.

For example, let's write several shell commands that can then be assembled into scripts:
  /** *    * * @param i  * @return  */ public static String doSleep(int i) { return "adb shell 'sleep " + i + "' ;"; } /** *   * * @param x1  * @param y1  * @param x2  * @param y2  * @return  */ public static String doSwipe(int x1, int y1, int x2, int y2) { return "adb shell input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " ;"; } /** *   * * @param x * @param y * @return  */ public static String doTap(int x, int y) { return "adb shell input tap " + x + " " + y + " ;"; } /** *      * * @param text  * @return  */ public static String doInputText(String text) { return "adb shell input text " + text + " ;"; } /** *   * * @param keycode   * @return  */ public static String doInputKeyevent(int keycode) { return "adb shell input keyevent " + keycode + " ;"; } /** *   (     ) * * @param message  * @return  */ public static String echo(String message) { return "echo '" + message + "' ;"; } 

These commands can also be combined into various scripts:
  /** *   * * @return  */ public static String sampleScript(){ String command = ""; command = command .concat(doSwipe(100, 200, 100, 500)) .concat(doSleep(1)) .concat(doTap(100, 150)) .concat(doSleep(1)) .concat(doInputText(" ")) .concat(doSleep(1)) .concat(doInputKeyevent(KeyEvent.KEYCODE_ENTER)) .concat(doSleep(1)) .concat(echo("SCRIPT_FINISHED")); return command; } 


Calling this script is very simple:
 runCommand(sampleScript()); 

At 1 second intervals, this script first snaps, then tapes, then enters the text, emulates pressing the Enter key, and then sends a message with a completion signal.

Now the fun part. This script will run in the background for a few seconds, since there are delays in it. Upon its completion, this message will be in the input stream. In my example, I convert it to a string, and then call the handleBashCommandsResult (result) method, which accepts this string as an input parameter. In this method, the result can be compared
  /** *  ,    (      echo) * * @param result  . */ private void handleBashCommandsResult(String result) { if (result.contains("SCRIPT_FINISHED")) { //         } else if (.....){ //     -    } else { //       } } 

On this in general, that's all. In the handleBashCommandsResult method, you can perform, for example, some checks and start execution of one of several other scripts, depending on the results of this check. Anyway, I briefly described how to set up interaction between shell scripts and Java code, which I actually wanted.

I hope someone can come in handy. If you have any questions, I will try to answer you.

Source: https://habr.com/ru/post/264135/


All Articles