android Accessibility service
偶然間看到了這篇文章,http://www.pingwest.com/kill-process-in-a-smart-way/,雖然對百度的產品沒有太大的興趣,但是它的超強加速功能還是挺迷人的,就研究了一下。剛才文章裡面介紹是利用協助工具功能服務實現類比點擊來實現的。
所以先要瞭解下協助工具功能服務,Accessibility service. 網上關於AccessibilityService的闡述和用法已經很多很詳細了,能翻牆且英文沒問題就直接看官網:http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html,另外這個翻譯的還不錯,http://wiki.eoeandroid.com/Building_Accessibility_Services
在這裡主要描述一下,“類比點擊”的實現原理。
首先要用到API 14添加的方法AccessibilityEvent.getSource()方法,API 18添加的AccessibilityNodeInfo.findAccessibilityNodeInfosByViewId()方法,AccessibilityNodeInfo.performAction()方法;
然後通過AccessibilityEvent.getSource()方法能夠從資源中獲得視窗的內容和行為,AccessibilityNodeInfo,通過findAccessibilityNodeInfosByViewId()方法可以確定我們要點擊的按鈕;
研究了源碼找到了,Force stop對應的view id是R.id.left_button,findAccessibilityNodeInfosByViewId(“com.android.settings:id/left_button”);
確定了要點擊的按鈕之後,就要執行點擊,AccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)。
到這一步,我們已經實現了,點擊強制停止,但是點擊“強制停止”之後,還會彈出一個讓我們確認的dialog,所以還要點擊確認。
同樣確認按鈕的view id是button1,但是不知道為什麼用findAccessibilityNodeInfosByViewId()方法不能找到確認按鈕,可能AlertDialog有些特殊。又廢了一番周折,最後想到確認按鈕在Dialog中的位置是固定的,所以通過AccessibilityEvent.getText().get(3),來擷取確認按鈕的text值,然後調用AccessibilityNodeInfo.findAccessibilityNodeInfosByText(String text),最後執行點擊事件AccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)。
下面是代碼:
@SuppressLint(NewApi)private void processKillApplication(AccessibilityEvent event) {//Log.d(ATM, event.getEventType()+++);if (event.getSource() != null) {if (event.getPackageName().equals(com.android.settings)) {List stop_nodes = event.getSource().findAccessibilityNodeInfosByViewId(com.android.settings:id/left_button);//Log.d(ATM, stop_nodes.toString());if (stop_nodes!=null && !stop_nodes.isEmpty()) {AccessibilityNodeInfo node;for(int i=0; i ok_nodes = null;if(event.getText() != null && event.getText().size() == 4) {ok_nodes = event.getSource().findAccessibilityNodeInfosByText(event.getText().get(3).toString());}if (ok_nodes!=null && !ok_nodes.isEmpty()) {AccessibilityNodeInfo node;for(int i=0; i