一、前言node
網上關於Android輔助服務的使用方式已經很是豐富了,因此也不在意再多我這一篇了:-D。有同窗說這是重複造輪子,題主很贊成,但反過來講,若是本身沒有能力造出輪子,還對重複造輪子嗤之以鼻,那……,再者,題主認爲,本身重複一遍別人的輪子,踩踩坑,要比只看別人的輪子在理解上深入的多,再不濟,記錄下來權當筆記吧android
二、實現步驟web
一、自定義服務繼承系統的AccessibilityService服務,重寫必要方法api
二、配置AndroidManiFest.xml,增長服務相關配置ide
三、在res下新建文件夾xml,新建xml文件,配置服務的相關配置,並在AndroidManifest.xml指定該配置文件(也能夠在服務類的onServiceConnected中配置)測試
四、打包、安裝apk,在「設置裏」找到輔助服務並開啓便可。ui
三、具體實現spa
一、自定義服務,必須實現的方法是onAccessibilityEvent(AccessibilityEvent event)和onInterrupt(),代碼以下.net
public class AccessibilityServiceTest extends AccessibilityService { //可在此方法中配置服務的相關配置,代替配置文件的方式 @Override protected void onServiceConnected() { super.onServiceConnected(); Log.d("XLZH:", "OnServiceConnected"); } //監聽事件類型,根據事件類型不一樣作不一樣的處理。事件類型較多,各位能夠打印出來篩選出來本身要監聽的事件類型 @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override public void onAccessibilityEvent(AccessibilityEvent event) { Log.d("XLZH:", event.toString()); int eventType = event.getEventType(); switch (eventType) { case AccessibilityEvent.TYPE_VIEW_SCROLLED: //獲取發生該事件的頁面根view AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); //根據id查找須要點擊的節點,返回的是一個List List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("com.tendcloud.demo:id/pager"); //獲取List的第一個節點,並打印該節點的child數目及類名 AccessibilityNodeInfo contentNodeInfo = list.get(0); Log.d("XLZH size:", String.valueOf(contentNodeInfo.getChildCount())); Log.d("XLZH class: ", String.valueOf(contentNodeInfo.getClassName())); //經過查找文本的方式得到節點
if(contentNodeInfo.findAccessibilityNodeInfosByText("button_test1") != null){ Log.d("XLZH :", "first page"); } if(contentNodeInfo.findAccessibilityNodeInfosByText("button1") != null){ Log.d("XLZH :", "second page"); } if(contentNodeInfo.findAccessibilityNodeInfosByText("tvweb") != null){ Log.d("XLZH :", "third page"); } break; } } @Override public void onInterrupt() { } }
二、配置AndroidManiFest.xml。以下code
<service android:name=".AccessibilityServiceTest" android:label="AccessibilityServiceTest" <!--聲明權限,而不是申請權限-->
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:exported="false"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <!--配置服務服務配置文件路徑--> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_xml" /> </service>
三、編寫輔助服務的配置文件
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/description" //在設置中顯示的內容 android:accessibilityEventTypes="typeAllMask" //監聽事件的類型 android:accessibilityFeedbackType="feedbackGeneric" //反饋的類型 android:notificationTimeout="100" //設置超時時間 android:accessibilityFlags="flagDefault" //配置flag android:canRetrieveWindowContent="true" //能夠獲取窗口上的對象的值 android:packageNames="com.tendcloud.demo" /> //配置要監聽的包名
四、其餘
一、有個印象深入的坑是在配置AndroidManifest.xml時,不是使用<user-permission ...>,而是要在Service裏聲明服務,即有BIND_ACCESSIBILITY_SERVICE的應用才能訪問該服務,而不是該服務須要申請這個權限
二、原本想是否能夠只要該Service,而不要Activity,通過查閱資料、親自嘗試,結果是……不行!
三、還有一個坑,至今沒有解決。測試的目的apk界面, 以下
如代碼所示,原本想經過查找控件肯定當前是那個頁面,測試結果發現當在第一個頁面的時候,Child包括第二個頁面中的控件,當在第二個頁面的時候,Child包括第一個、第2、第三個頁面中的控件,當在第三個頁面的時候,Child包括第二個頁面和第三個頁面中的控件。
具體緣由不明白,有大神能夠測試並指導一下,謝謝。