目錄html
Accessibility:無障礙,又稱輔助性功能.
AccessibilityService:無障礙服務,繼承於 Serveice. 它能夠監聽操做、檢索窗口內容、啓用觸摸瀏覽等android
在原生android設備中 Settings 應用程序菜單中有一項 Accessibility(無障礙). 該項菜單下有項 TalkBack功能:它能讀取屏幕上的內容,對於盲人和視力低弱人士而言,這項功能很是實用. 還有不知道你們是否會注意,使用三方app store批量自動安裝app時,此時Accessibility中會出現 "xx自動安裝"功能. 那麼這些功能是怎實現的呢?是如何實現的呢?—— AccessibilityService
git
在《UiAutomator2.0 - 控件實現點擊操做原理》中已經分析了UiAutomator自動測試點擊操做的具體實現過程,最終的操做是由 UiAutomation 這個類實現的.從這個類註釋能夠看出:能夠將UiAutomation看做特殊AccessibilityService 類型,它不爲服務生命週期提供掛鉤,而且公開了對UI測試自動化有用的其餘API.也就是說UiAutomator2.0是經過 AccessibilityService來實現的.
github
a.爲了驗證上面的猜測是否正確,在Android studio中新建app工程->建一個服務類MyAccessibility繼承 AccessibilityServiceshell
package com.zzw.barrierfree; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.util.Log; import android.view.accessibility.AccessibilityEvent; public class MyAccessibility extends AccessibilityService { private static final String TAG = MyAccessibility.class.getSimpleName(); // 初始化服務操做 @Override protected void onServiceConnected() { Log.d(TAG, "onServiceConnected: ------- config accessibility "); AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo(); // 響應某個應用的事件,包名爲應用的包名。設置爲null等同於全部包名 accessibilityServiceInfo.packageNames = new String[]{ "com.android.settings"}; // 響應時間的類型,事件分不少種:單擊、長按、滑動。 這裏設置爲全部事件 accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; // 設置回饋給用戶的方式,語音播出仍是振動 accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN; // 響應時間的設置 accessibilityServiceInfo.notificationTimeout = 1000; setServiceInfo(accessibilityServiceInfo); } // 響應AccessibilityEvent的事件 @Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventTypeId = event.getEventType(); String eventText = ""; Log.d(TAG, "onAccessibilityEvent: ----------------Start--------------"); switch (eventTypeId) { case AccessibilityEvent.TYPE_VIEW_CLICKED: eventText = "TYPE_VIEW_CLICKED"; break; case AccessibilityEvent.TYPE_VIEW_FOCUSED: eventText = "TYPE_VIEW_FOCUSED"; break; case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED: eventText = "TYPE_VIEW_LONG_CLICKED"; break; case AccessibilityEvent.TYPE_VIEW_SELECTED: eventText = "TYPE_VIEW_SELECTED"; break; case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: eventText = "TYPE_VIEW_TEXT_CHANGED"; break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: eventText = "TYPE_WINDOW_STATE_CHANGED"; break; case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: eventText = "TYPE_NOTIFICATION_STATE_CHANGED"; break; case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END: eventText = "TYPE_TOUCH_EXPLORATION_GESTURE_END"; break; case AccessibilityEvent.TYPE_ANNOUNCEMENT: eventText = "TYPE_ANNOUNCEMENT"; break; case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START: eventText = "TYPE_TOUCH_EXPLORATION_GESTURE_START"; break; case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: eventText = "TYPE_VIEW_HOVER_ENTER"; break; case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: eventText = "TYPE_VIEW_HOVER_EXIT"; break; case AccessibilityEvent.TYPE_VIEW_SCROLLED: eventText = "TYPE_VIEW_SCROLLED"; break; case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: eventText = "TYPE_VIEW_TEXT_SELECTION_CHANGED"; break; case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: eventText = "TYPE_WINDOW_CONTENT_CHANGED"; break; } eventText = eventText + ":" + eventTypeId; Log.e(TAG, "onAccessibilityEvent:"+ eventText); Log.d(TAG, "onAccessibilityEvent: -------------------End----------------"); } // 打斷獲取事件的過程 @Override public void onInterrupt() { } }
b.在AndroidManifest.xml中配置服務app
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zzw.barrierfree"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:theme="@style/AppTheme.NoActionBar"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--服務配置--> <service android:name=".MyAccessibility" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" > <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> </service> </application> </manifest>
c.運行該app,此時在設置->無障礙中會出現配置的服務, 可是該服務處於關閉狀態
d.手動開啓該服務,打開android studio中的logcat. 操做(點擊/滑動等)設置應用程序,會出現相應的響應事件.如下是命令開啓方式:
adb shell settings put secure enabled_accessibility_services com.zzw.barrierfree/com.zzw.barrierfree.MyAccessibility
adb shell settings put secure accessibility_enabled 1
e.結合上篇的點擊時監聽的相應事件,與log中打印的事件是一致的. 那就說明:點擊/滑動等操做是經過 AccessibilityService 監聽對應的視圖或窗口狀態來判斷操做是否成功執行.ide