91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Monkey源碼分析番外篇之Android注入事件的三種方法比較

發布時間:2020-07-08 08:45:11 來源:網絡 閱讀:279 作者:zhukev 欄目:移動開發

原文: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這兩個事件注入方法。

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注入事件的三種方法比較
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事件,你將會得到一個強制關閉的消息:
Monkey源碼分析番外篇之Android注入事件的三種方法比較

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);
Monkey源碼分析番外篇之Android注入事件的三種方法比較
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使用到的注入事件方式其實和方法一提到的通過WindowManager.injectPointerEvents是一樣的,所以穿的都是同一條內褲,只是Robotium出來走動的時候套上條時尚喇叭褲,而以上直接調用WindowManager的方式就猶如只穿一條內褲出街的區別而已。

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注入事件的三種方法比較

adb shell su chmod 666 /dev/input/event3 
You will need root to run the chmod command.

你將需要root權限來運行chmod命令。


 

作者

自主博客

微信

CSDN

天地會珠海分舵

http://techgogogo.com


服務號:TechGoGoGo

掃描碼:

Monkey源碼分析番外篇之Android注入事件的三種方法比較

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

许昌市| 古蔺县| 拜泉县| 石狮市| 临洮县| 东乡族自治县| 新巴尔虎右旗| 伊春市| 乌兰浩特市| 扎兰屯市| 卫辉市| 砀山县| 家居| 长寿区| 敖汉旗| 惠水县| 霍林郭勒市| 赤水市| 旬邑县| 仙桃市| 奉节县| 肇源县| 阜城县| 巴彦县| 锡林浩特市| 安徽省| 长宁区| 凤凰县| 桓台县| 通河县| 南陵县| 万安县| 峡江县| 尚义县| 会泽县| 临桂县| 铜川市| 岫岩| 枝江市| 江城| 高尔夫|