您好,登錄后才能下訂單哦!
原文:http://www.pocketmagic.net/2012/04/injecting-events-programatically-on-android/#.VEoIoIuUcaV
往下分析monkey事件注入源碼之前先了解下在android系統下事件注入的方式,翻譯一篇國外文章如下。
該方法和其他所有內部沒有向外正式公布的APIs一樣存在它自己的風險。
The idea is to get an instance of WindowManager in order to access the injectKeyEvent / injectPointerEvent methods.
原理是通過獲得WindowManager的一個實例來訪問injectKeyEvent/injectPointerEvent這兩個事件注入方法。
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:
//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
這種方法能在你的應用中很好的工作,但,也僅僅只能在你的應用中而已
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 permissionNot much joy, as INJECT_EVENTS is a system permission. A possible solution is discussed here and here.
苦逼了吧,畢竟INJECT_EVENTS是需要系統權限的,一些可能解決的方案在這里和這里有討論到。
(譯者注:請查看本人上一篇翻譯的《Monkey源碼分析番外篇之WindowManager注入事件如何跳出進程間安全限制》里面有更詳細針對這個問題的描述)
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);
在應用內操作的話完全沒有問題,但一旦跳出這個應用去觸發按鍵事件的話就會崩潰。不是因為這個方法不工作,而是因為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使用到的注入事件方式其實和方法一提到的通過WindowManager.injectPointerEvents是一樣的,所以穿的都是同一條內褲,只是Robotium出來走動的時候套上條時尚喇叭褲,而以上直接調用WindowManager的方式就猶如只穿一條內褲出街的區別而已。
public void sendPointerSync(MotionEvent event) { validateNotAppThread(); try { (IWindowManager.Stub.asInterface(ServiceManager.getService("window"))) .injectPointerEvent(event, true); } catch (RemoteException e) { } }
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)。為了向這個設備注入事件,你必須讓它能可寫。所以請先做以下動作:
adb shell su chmod 666 /dev/input/event3You will need root to run the chmod command.
你將需要root權限來運行chmod命令。
作者 | 自主博客 | 微信 | CSDN |
天地會珠海分舵 | http://techgogogo.com | 服務號:TechGoGoGo 掃描碼:
| 向AI問一下細節 免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。 猜你喜歡最新資訊相關推薦相關標簽AI
助 手
许昌市|
古蔺县|
拜泉县|
石狮市|
临洮县|
东乡族自治县|
新巴尔虎右旗|
伊春市|
乌兰浩特市|
扎兰屯市|
卫辉市|
砀山县|
家居|
长寿区|
敖汉旗|
惠水县|
霍林郭勒市|
赤水市|
旬邑县|
仙桃市|
奉节县|
肇源县|
阜城县|
巴彦县|
锡林浩特市|
安徽省|
长宁区|
凤凰县|
桓台县|
通河县|
南陵县|
万安县|
峡江县|
尚义县|
会泽县|
临桂县|
铜川市|
岫岩|
枝江市|
江城|
高尔夫|
|