Monkeyソース分析番外編のAndroid注入事件の3つの方法の比較


原文:http://www.pocketmagic.net/2012/04/injecting-events-programatically-on-android/#.VEoIoIuUcaV
monkeyイベント注入ソースコードを下に分析する前にandroidシステムでのイベント注入の方法を理解し、海外の文章を翻訳して以下のようにします.
Method 1: Using internal APIs
方法1:内部APIsを使う
This approach has its risks, like it is always with internal, unpublished APIs.
この方法は他のすべての内部で正式に公表されていないAPIsと同様に独自のリスクがある.
The idea is to get an instance of WindowManager in order to access the injectKeyEvent/injectPointerEvent methods.
WindowManagerのインスタンスを取得することによって、injectKeyEvent/injectPointerEventの2つのイベント注入方法にアクセスすることが原理です.
IBinder wmbinder = ServiceManager.getService( "window" ); 
IWindowManager m_WndManager = IWindowManager.Stub.asInterface( wmbinder );
The ServiceManager and WindowsManager are defined as Stubs. We can then bind to these services and call the methods we need. 
ServiceManagerとWindowsmanagerは、スタブStubsクラスとして定義されます.私たちは必要に応じてこれらのサービスをバインドしてアクセスする方法です.To send a key do the following:次のようにイベントを送信します.
// key down
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A ),true );
// key up
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A ),true );
To send touch/mouse events use:
touch/mouseイベントの送信:
//pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0), true);
m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0), true);
This works fine, but only inside your application
この方法はあなたのアプリケーションでよく機能しますが、あなたのアプリケーションでしかできません.Monkey源码分析番外篇之Android注入事件的三种方法比较_第1张图片 The moment you're trying to inject keys/touch events to any other window、you'll get a force close because of the following exception:
他のウィンドウにkeys/touchイベントを注入すると、強制的に閉じるメッセージが表示されます.
E/AndroidRuntime(4908): java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
Not much joy, as INJECT_EVENTS is a system permission. A possible solution is discussed  here and  here.
苦いでしょう、結局INJECT_EVENTSにはシステム権限が必要であり,いくつかの可能な解決策がここで議論されている.
(注:前回翻訳した「Monkeyソース分析番外編のWindowManager注入イベントがプロセス間セキュリティ制限からどのように飛び出すか」には、この問題についてより詳細な説明があります)
Method 2: Using an instrumentation object
方法2:instrumentationオブジェクトの使用
This is a clean solution based on public API, but unfortunately it still requires that INJECT_EVENTS permission.
以上の隠しインタフェースとメソッドに対して、これは比較的クリーン(上は隠しているのでandroidが不潔でお勧めしない方法で取得する必要がある)な方法ですが、
残念なことに、それはまだ上のJINECTを持っています.EVENTSというシステムアプリケーション(基本的にはandroid自身が提供するmonkeyなど)だけが許可される権限の問題です.
Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );

For touch events you can use:
以下に、タッチイベントの例を示します.
//pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0);
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0);

All good inside the test application, and will crash instantly when trying to inject keys to outside apps, not because the approach doesn't work, but because Android Developers have chosen so. Thanks guys, you rock! Not.
アプリケーション内で操作すると全く問題ありませんが、このアプリケーションから飛び出してキーイベントをトリガーするとクラッシュします.この方法が働かないからではなく、android開発者が制限したからです.ありがとうandroidの開発者たち、あなたは牛を追い詰めます!おべっかを使う.By looking at sendPointerSync's code, you will quickly see it uses the same approach as presented in method 1). So this is the same thing,but packed nicely in a easy to use API:sendPointerSyncの対応コードを分析することにより、instrumentationが使用する注入イベントの方式と方法についてWindowManagement.injectPointerEventsは同じなので、同じパンツを着ていますが、Robotiumが出てくるときにファッションラッパパンツを着ているだけで、以上WindowManagerを直接呼び出すのはパンツを1枚だけ履いて街を出るような違いです.
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
try {
(IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
.injectPointerEvent(event, true);
} catch (RemoteException e) {
}
}

Method 3: Direct event injection to/dev/input/eventX
方法3:デバイス/dev/input/eventXにイベントを直接注入する
Linux exposes a uniform input event interface for each device as/dev/input/eventX where X is an integer. We can use it directly and skip the above Android Platform permission issues.
linuxは、システムデバイスの方法でユーザに統合されたイベント注入インタフェース/dev/input/eventX(Xは整数を表す)を暴露した.以上のプラットフォーム(androidというチャンスlinuxのプラットフォーム)の制限問題を直接スキップすることができます.For this to work, we will need root access, so this approach only works on a rooted device.
しかし、これは仕事が必要であれば、rootedが過ぎた設備が必要です.
By default the eventX files have the permission set for 660 (read and write for Owner and Group only). To inject keys from our application, we need to make it writable. So do this first:
デバイスファイルeventXのデフォルトは660に設定されています(Ownerと同じグループのメンバーは読み書きがあり、ownerはrootです).この装置にイベントを注入するためには、書くことができるようにしなければなりません.Monkey源码分析番外篇之Android注入事件的三种方法比较_第2张图片
adb shell
su
chmod 666 /dev/input/event3 

You will need root to run the chmod command.
chmodコマンドを実行するにはroot権限が必要です.
 
作成者
自主ブログ
微信
CSDN
天地会珠海分舵
http://techgogogo.com
サービス番号:TechGoGoGoスキャンコード:Monkey源码分析番外篇之Android注入事件的三种方法比较_第3张图片
http://blog.csdn.net/zhubaitian