Android AccessibilityService(輔助服務) 使用示例

一、前言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包括第二個頁面和第三個頁面中的控件。

具體緣由不明白,有大神能夠測試並指導一下,謝謝。

測試對象apk

測試代碼

相關文章
相關標籤/搜索