輔助功能 英文稱為Accessibility
針對有部分缺陷的群體,如視覺、聽覺等存在障礙,他們不能看到完整的螢幕或者使用觸屏,google提供了Accessibility功能和服務幫助這些使用者更加簡單地操作裝置。這其中最主要的一個類就是AccessibilityService,AccessibilityService是一個系統服務,
它運作在背景,并且能夠收到由系統發出的一些事件,比如通知狀态、按鈕被點選了等等。界面中産生的任何變化都會由系統通知給AccessibilityService.這就像螢幕監視着界面的一舉一動。
AccessibilityService生命周期
AccessibilityService繼承了service,他是在背景運作的。
1、AccessibilityService是系統服務,該服務完全由系統管理,并遵循已有的服務周期.
2、開啟一個服務隻能由使用者在設定中打開,而關閉則隻能由使用者在設定中關閉或者服務本身通過diableSelf()方法關閉
3、系統綁定該服務之後,會調用onServiceConnected()方法,這個方法可以被重寫,在這裡可以做一些初始化的操作.
4、在實際的操作實驗中發現,即便手動開啟該服務,在6.0以上的系統經過一段時間也會自動關閉。
在實際開發中,可以繼承AccessibilityService類,然後有選擇的實作其中的一部分函數,就可以實作一些特殊的功能。
AccessibilityService函數
1.onAccessibilityEvent(AccessibilityEvent event
)必須重寫。AccessibilityEvent是一個事件類,裡面封裝了許多字段,表示各種不同的事件(通知、視窗内容)。形參event表示事件變化,接收來的AccessibilityEvent是可以經過過濾的,過濾是在配置工作時設定的。
2.onInterrupt()必須重寫。這個在系統想要中斷AccessibilityService返給的響應時會調用。在整個生命周期裡會被調用多次。
3.onServiceConnected()可選。在系統成功連接配接上這個AccessibilityService會調用。在這個方法裡主要做初始化工作。
4.onUnbind()可選。在系統将要關閉這個AccessibilityService會被調用。在這個方法中主要做釋放資源的工作。
聲明
AccessibilityService和在menifest中聲明其他service一樣,但要額外做兩件事
1.配置<intent-filter>,其name為固定的
2.聲明BIND_ACCESSIBILITY_SERVICE權限,
<service
android:name=".AutoReplyService"
android:enabled="true"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
</service>
配置
AccessibilityService可以添加一些配置資訊,目的是隻接收一些特定的事件.例如:監聽特定的包、android給我們提供2種配置方法:
方法1:meta-data标簽方式:
在manifest聲明的servce中提供一個meta-data标簽,然後通過android:resource指定相應的配置檔案(在res目錄下建立xml檔案,并在其中建立配置檔案accessibilityservice.xml):
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/auto_reply_service_config"/>
方法2:調用setServiceInfo(AccessibilityServiceInfo)方式:AccessibilityServiceInfo用于配置AccessibilityService資訊,類中包含了大量用于配置的常量字段。
1.這個方法可以在任何時候調用,動态的去改變service配置資訊
2.這個方法隻能用來配置動态屬性,如:eventTypes,feedbackType,flags,notificationTimeout等。
通常是在onServiceConnected()進行配置
啟動服務
當我們配置完成,進行運作後就可以安裝到手機.安裝成功後,在設定->輔助功能中便可以找到我們的服務.該服務預設處在關閉狀态,需要手動開啟.
擷取界面指定控件
Android中的View體系是一個樹形結構,是以每一個View就是一個節點。安卓系統提供了兩個方法讓我們來進行查找想要的節點View
第一種是通過節點View的Text内容來查找
findAccessibilityNodeInfosByText("查找内容") 這種方式查找,對于有文本内容的哪些控件,可以使用這種方式快速的找到。
第二種是通過節點View在xml布局中的id名稱
findAccessibilityNodeInfosByViewId("@id/xxx")我們可以通過HierarchyView查找指定控件的id,
模拟點選
在找到指定的View節點,調用方法模拟事件:
performAction(AccessibilityNodeInfo.ACTION_CLICK)調用這個方法,AccessibilityNodeInfo類中封裝了與控件有關的相關字段和方法,這裡的參數就是指定事件的名稱,這個和AccessibilityEvent中監聽的那些事件是一一對應的,這裡是模拟點選事件,同理也可以模拟View的滾動事件,長按事件等。
執行個體
QQ自動回複:實作QQ自動回複,其實就是監聽QQ的包名以及通知變化,當QQ來消息的時候,自動跳到聊天界面,填充消息并點選發送。(類似于自動化測試)
具體步驟:
1. 監聽QQ發出的Notification,此時要判斷是否鎖屏狀态
2. 點選Notification的contentIntent屬性,進入到QQ詳情頁
3. 從根節點開始,查找指定的edittext,并進行内容填充。
4. findAccessibilityNodeInfosByText(發送)
調用performAction(AccessibilityNodeInfo.ACTION_CLICK)實作模拟點選
總結一下,輔助功能的大概思路
第一、有選擇的監控界面變化,并進行通知,有需要的進行跳轉
第二、當有event發生時,尋找到我們想要的View節點
第三、模拟操作,實作特定功能
坑點及注意事項
1.包被混淆,之前通過AndroidDevice Monitor檢視ID,然後根據findAccessbilityNodeInfoById ()去比對節點,包被混淆之後每個版本不一樣
2.很難找出沒有文本的控件,如EditText,ImageView
3、部分手機在手動開啟一段時間後自動關閉,導緻部分功能不穩定。
4、對于有手機鎖屏密碼的無法打開其螢幕
輔助功能其他的用途:
1、 微信搶紅包:監聽微信紅包,當收到紅包時,自動模拟點選
2、 強制停止應用:我們可以監聽系統的應用詳情頁面,然後找到:結束運作的節點View,然後模拟點選即可
3、 檢測自己的app是否在前台。