手の動きでモンスターボール投げ! 3

↑ これの続きです。

システム構成
(1):ToF AR が入った Android アプリで手認識
(2):(1) から信号受信しスワイプ操作を実行するスマホ上のプログラム
(3):ポケモンGo

前回、Java プログラムを Android スマホ上で動作させることができました。今回は Java プログラムからタッチ操作を発生させることでポケモンGoのモンスターボールを投げる、という部分の技術解説をしたいと思います。

動作の様子

ADB.exe からのプログラム実行により、下から上へのスワイプ動作が実行されます。ポケモンGo上ではモンスターボールを投げる動作になります。

プログラムは以下の GitHub 上で公開しています。


解説

今回開発、実行したのは以下のプログラムになります。

TouchServer2.java

main メソッド(関数)で具体的にタッチ操作をしています。この部分を変更すれば、様々な操作を実現できます。

    public static void main(String[] args) throws InterruptedException {
        // タッチする座標
        // 横向き縦向き、スマホの画面解像度などで調整が必要
        int x = 500;
        int y = 2000;

        // タッチダウン
        Motion(MotionEvent.ACTION_DOWN, x, y, 0);
        // ボールをつかむまで一定時間必要なのでウェイト
        Thread.sleep(200);

        // タッチ箇所をループで徐々に上に移動させていく
        for(int i = 0; i < 10; i++){
            y -= 20 * (i + 1);
            Motion(MotionEvent.ACTION_MOVE, x, y, 0);
            Thread.sleep(15);
        }

        // 最後にタッチアップ
        Motion(MotionEvent.ACTION_UP, x, y, 0);
    }

Motion メソッドに引数として
・Down/Move/Up のいずれか
・X 座標と Y 座標
を入れています。

ウェイトが無いと一瞬で操作命令が走ってしまい、現実的にはあり得ないくらい早い操作となってしまいます。この場合、スマホ側で操作処理が行われないことがあります。そのため、Thread.sleep  メソッドを使ってウェイトを入れています。タッチ時に 200 milli sec、スワイプ移動中は 15 milli sec のウェイトを入れています。

このメソッド以外の部分ではInputManager や MotionEvent などのクラスを使用するための初期化処理やタッチ操作の具体的な処理を行っています。

InputManager にある injectInputEvent というメソッドが隠されているため reflection の仕組みを使って無理やり?使えるようにしています。

この仕組みを使えば、タッチ・スワイプ・ピンチイン・アウトなど様々な操作が実現できそうです。

ちなみに実装していて気づいたのですが、プログラムのビルド毎にアンインストールと内部アプリ名取得をやりなおす必要性があるようです。apk に関係無い部分は更新されないのかもしれません。内部アプリ名の取得方法は以下の記事の「5.Java プログラムを実行する」を参考にしてください。

次回予告

次回は (1) と (2) の通信部分の実装・解説を予定しています。

続きはこちら ↓


この記事が気に入ったらサポートをしてみませんか?