AndroidでのJavaとシェルスクリプトの相互運用性

私の現在のプロジェクトでは、シェルスクリプトの実行をコードから直接実装する必要がありました。



最新の状態に保つために、この記事を読むことをお勧めします: Android環境でのシェルスクリプト



Shell言語の機能を非常によく説明していますが、スクリプト自体に加えて、Javaメソッドを実行する必要がありました。



開発プロセスでは、Android_x86イメージが使用されました。 ただし、ルート化された電話を使用できます(スーパーユーザー権限が必要です)。



Javaスクリプト自体の実行は非常に簡単です。

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





Android_x86では、スクリプトをプロセスに直接送信でき、スクリプトが実行されます。 電話を使用する場合、次の行:

 Process child = Runtime.getRuntime().exec(command);
      
      





これらと交換する必要があります:

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





これをどのように説明できるかわかりませんが、電話ではスクリプトを実行する前にコマンドシェルを実行する必要があります。 それ以外は、すべて同じです。



たとえば、スクリプトにアセンブルできるいくつかのシェルコマンドを作成します。

  /** *    * * @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 + "' ;"; }
      
      





これらのコマンドは、さまざまなスクリプトに組み合わせることができます。

  /** *   * * @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; }
      
      







このスクリプトの呼び出しは非常に簡単です。

 runCommand(sampleScript());
      
      





このスクリプトは、1秒間隔で最初にスワイプしてからタップしてテキストを入力し、Enterキーを押すことをエミュレートして、完了のシグナルを含むメッセージを送信します。



今から楽しい部分です。 このスクリプトは遅延があるため、バックグラウンドで数秒間実行されます。 完了すると、このメッセージは入力ストリームに含まれます。 この例では、文字列に変換し、その後、この文字列を入力パラメーターとして受け取るhandleBashCommandsResult(result)メソッドを呼び出します。 この方法では、結果を比較できます。

  /** *  ,    (      echo) * * @param result  . */ private void handleBashCommandsResult(String result) { if (result.contains("SCRIPT_FINISHED")) { //         } else if (.....){ //     -    } else { //       } }
      
      





それが基本的にすべてです。 handleBashCommandsResultメソッドでは、たとえば、いくつかのチェックを実行し、このチェックの結果に応じて、いくつかの他のスクリプトのいずれかの実行を開始できます。 いずれにせよ、基本的に必要だったシェルスクリプトとJavaコード間の相互作用を確立する方法について簡単に説明しました。



誰かが役に立つといいな。 ご質問がある場合は、お答えします。



All Articles