編輯:關於Android編程
方法1:使用內部APIs
該方法和其他所有內部沒有向外正式公布的APIs一樣存在它自己的風險。原理是通過獲得WindowManager的一個實例來訪問injectKeyEvent/injectPointerEvent這兩個事件注入方法。
復制代碼 代碼如下:
IBinder wmbinder = ServiceManager.getService( "window" );
IWindowManager m_WndManager = IWindowManager.Stub.asInterface( wmbinder );
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 );
發送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);
這種方法能在你的應用中很好的工作,但,也僅僅只能在你的應用中而已
一旦你想要往其他窗口注入keys/touch事件,你將會得到一個強制關閉的消息:
方法2: 使用instrumentation對象
相對以上的隱藏接口和方法,這個是比較干淨(上面的是隱藏的,故需要用到android不干淨不推薦的方法去獲取)的方式,但不幸的事它依然有上面的JINECT_EVENTS這個只有系統應用(基本上就是android自己提供的,如monkey)才被允許的權限問題。
復制代碼 代碼如下:
Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );
以下是觸摸事件實例:
復制代碼 代碼如下:
//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的開發者們,你牛逼!個屁。
通過分析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) {
}
}
方法3:直接注入事件到設備/dev/input/eventX
linux以系統設備的方式向用戶暴露了一套統一的事件注入接口/dev/input/eventX(其中X代表一個整數)。我們可以直接跳用而跳過以上的平台(android這個機遇linux的平台)限制問題。但是這需要工作的話,你需要rooted過的設備。
設備文件eventX默認是被設置為660這個權限的(Owner和同組成員有讀寫,而owner是root)。為了向這個設備注入事件,你必須讓它能可寫。所以請先做以下動作:
復制代碼 代碼如下:
adb shell
su
chmod 666 /dev/input/event3
你將需要root權限來運行chmod命令。
我們通常會在App的UI中嵌入WebView,用來實現某些功能的動態更新。在4.4版本之前,Android WebView基於WebKit實現。不過,在4.4版本之後,A
此方法適用於所有母控件無法獲取焦點的情況 開發中很常見的一個問題,項目中的listview不僅僅是簡單的文字,常常需要自己定義listview,自己的Adapter去繼承
一、背景這個選題很大,但並不是一開始就有這麼高大上的追求。最初之時,只是源於對Xposed的好奇。Xposed幾乎是定制ROM的神器軟件技術架構或者說方法了。它到底是怎麼
要完成一個輪播圖片,首先想到的應該是使用ViewPager來實現。ViewPager已經有了滑動的功能,我們只要讓它自己滾動。再加上下方的小圓點就行了。所以我們本次的自定