1、前言
網上關於Android輔助服務的使用方式已經非常豐富了,所以也不在乎再多我這一篇了:-D。有同學說這是重復造輪子,題主很同意,但反過來說,如果自己沒有能力造出輪子,還對重復造輪子嗤之以鼻,那……,再者,題主認為,自己重復一遍別人的輪子,踩踩坑,要比只看別人的輪子在理解上深刻的多,再不濟,記錄下來權當筆記吧
2、實現步驟
1、自定義服務繼承系統的AccessibilityService服務,重寫必要方法
2、配置AndroidManiFest.xml,增加服務相關配置
3、在res下新建文件夾xml,新建xml文件,配置服務的相關配置,並在AndroidManifest.xml指定該配置文件(也可以在服務類的onServiceConnected中配置)
4、打包、安裝apk,在“設置里”找到輔助服務並開啟即可。
3、具體實現
1、自定義服務,必須實現的方法是onAccessibilityEvent(AccessibilityEvent event)和onInterrupt(),代碼如下
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() { } }
2、配置AndroidManiFest.xml。如下
<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>
3、編寫輔助服務的配置文件
<?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" /> //配置要監聽的包名
4、其他
1、有個印象深刻的坑是在配置AndroidManifest.xml時,不是使用<user-permission ...>,而是要在Service里聲明服務,即有BIND_ACCESSIBILITY_SERVICE的應用才能訪問該服務,而不是該服務需要申請這個權限
2、本來想是否可以只要該Service,而不要Activity,經過查閱資料、親自嘗試,結果是……不行!
3、還有一個坑,至今沒有解決。測試的目的apk界面, 如下
如代碼所示,本來想通過查找控件確定當前是那個頁面,測試結果發現當在第一個頁面的時候,Child包括第二個頁面中的控件,當在第二個頁面的時候,Child包括第一個、第二、第三個頁面中的控件,當在第三個頁面的時候,Child包括第二個頁面和第三個頁面中的控件。
具體原因不明白,有大神可以測試並指導一下,謝謝。