Android AccessibilityService使用方法

  1. 原理
    大致簡述一下术健,谷歌已經(jīng)在View之宿、ViewGroup、TextView等控件的文字改變苛坚、滑動比被、UI變化埋下了接口,當這些狀態(tài)變化時控件會回調(diào)系統(tǒng)API泼舱,API系統(tǒng)然后對這些對象的數(shù)據(jù)進行組裝等缀,為了數(shù)據(jù)的安全性,系統(tǒng)會重新創(chuàng)建一些對象(AccessibilityEvent娇昙、AccessibilityNodeInfo)來間接保存這些數(shù)據(jù)尺迂,然后通過跨進程將這些數(shù)據(jù)返回給對應(yīng)的Service中。

  2. 使用范圍
    首先冒掌,輔助功能不可能直接操作外部對象噪裕,輔助功能只能在本進程調(diào)用指定系統(tǒng)方法,由系統(tǒng)再分發(fā)給指定外部對象股毫,輔助功能做的事基本和用戶能做的差不多(比如回復微信, 微信搶紅包)

AccessibilityService用法

  1. 首先, AccessibilityService本質(zhì)上也是一個Service, 所以在Manifest.xml 中還是需要注冊對應(yīng)的Service內(nèi)容, 并且聲明權(quán)限, 示例如下:
<service
            android:name=".RobService"
            android:enabled="true"
            android:exported="true"
            android:label="學習強國"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>

        <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/myaccessibility"/>
        </service>

其中resource中的配置項是單獨創(chuàng)建一個myaccessibility.xml文件

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"

    android:accessibilityEventTypes="typeAllMask" // 監(jiān)聽的事件類型, 這里表示全局監(jiān)聽
    android:accessibilityFeedbackType="feedbackGeneric" //反饋類型, 這里表示通用反饋
    android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
    android:canRetrieveWindowContent="true" //表示該服務(wù)能否訪問活動窗口中的內(nèi)容.也就是如果你希望在服務(wù)中獲取窗體內(nèi)容的話,則需要設(shè)置其值為true.
    android:notificationTimeout="100" // 接受事件的時間間隔
    android:canPerformGestures="true" //分發(fā)手勢
    android:packageNames="com.tencent.mm"/>
  1. 在注冊服務(wù)完成后, 就可以創(chuàng)建一個Service繼承AccessibilityService, 并且實現(xiàn)它的onServiceConnectedonAccessibilityEvent方法, 其中, 在onServiceConnected方法中放一些資源的初始化操作, 此方法會在開啟了AccessibilityService權(quán)限的時候被調(diào)用. 在onAccessibilityEvent實現(xiàn)對事件的處理, 比如屏幕改變事件, 消息通知事件.

  2. 控件的查找與操作
    控件的操作主要分為幾個步驟:

    1. 獲取到當前界面的根節(jié)點AccessibilityNodeInfo rootNode = getRootInActiveWindow();

    2. 通過id或者text文本查找到對應(yīng)的節(jié)點

      • 在sdk-tools/tools目錄下, 有一個monitor.bat腳本, 雙擊這個腳本打開Android Device Monitor
      • 在電腦連接了安卓手機并且開啟了USB調(diào)試模式的情況下, Android Device Monitor會顯示出對應(yīng)的手機, 點擊上面的Dump View按鈕, 此時工具會自動對當前手機界面進行分析, 并生成一個dump
      • 最后得到類似下圖, 用鼠標移動到對應(yīng)的控件上, 即可看到控件的屬性和文本等


        截圖

        控件屬性
    3. 對節(jié)點進行操作, 這里要注意到, 有一些程序做了特殊處理, 有時候在Android Device Monitor看到clickable屬性為true, 但不一定它就會響應(yīng)click事件, 是否響應(yīng)事件要按實際情況分析.

//獲取當前聊天頁面的根布局
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
List<AccessibilityNodeInfo> listChat = rootNode.findAccessibilityNodeInfosByViewId("android:id/text1"); //根據(jù)id查找控件
//List<AccessibilityNodeInfo> listChat = rootNode.findAccessibilityNodeInfosByText("發(fā)送"); //根據(jù)文本查找控件
for (AccessibilityNodeInfo nodeInfo : listChatRecord) {
   nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); //點擊控件
}
  1. 手勢
    Android提供了特殊類型的觸摸屏事件膳音,如捏合,雙擊铃诬,滾動祭陷,長按和退縮。這些都被稱為手勢趣席。
 //發(fā)送一個點擊事件
Path mPath=new Path();//線性的path代表手勢路徑,點代表按下,封閉的沒用
mPath.moveTo(500, 500);
service.dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription
(mPath, 手勢開始時間比如立即開始0, 手勢總時長比如100)).build(), 回調(diào)函數(shù)(可以為null), 回調(diào)的線程(null表示主線程));

擴展使用

  1. 使用webview通過js調(diào)用android代碼
    在android的方法定義中, 加上@JavaScriptInterface注釋后, 在webView.addJavascriptInterface(new JsInterface(), "Android");
    然后在js中執(zhí)行"Android.方法名"

附錄

  • accessibilityEventTypes的取值
    | constant | value | 描述 |
    | - | - | - |
    | typeAllMask|ffffffff|所有類型的事件
    |typeAnnouncement|4000|一個應(yīng)用產(chǎn)生一個通知事件
    |typeAssistReadingContext|1000000|輔助用戶讀取當前屏幕事件
    |typeContextClicked|800000|view中上下文點擊事件
    |typeGestureDetectionEnd|80000|監(jiān)測到的手勢事件完成
    |typeGestureDetectionStart|40000|開始手勢監(jiān)測事件
    |typeNotificationStateChanged|40|收到notification彈出消息事件
    |typeTouchExplorationGestureEnd|400|觸摸瀏覽事件完成
    |typeTouchExplorationGestureStart|200|觸摸瀏覽事件開始
    |typeTouchInteractionEnd|200000|用戶觸屏事件結(jié)束
    |typeTouchInteractionStart|100000|觸摸屏幕事件開始
    |typeViewAccessibilityFocusCleared|10000|無障礙焦點事件清除
    |typeViewAccessibilityFocused|8000|獲得無障礙的焦點事件
    |typeViewClicked|1|點擊事件
    |typeViewFocused|8|view獲取到焦點事件
    |typeViewHoverEnter|80|一個view的懸停事件
    |typeViewHoverExit|100|一個view的懸停事件結(jié)束兵志,懸停離開該view
    |typeViewLongClicked|2|view的長按事件
    |typeViewScrolled|1000|view的滾動事件,adapterview宣肚、scrollview
    |typeViewSelected|4|view選中想罕,一般是具有選中屬性的view,例如adapter
    |typeViewTextChanged|10|edittext中文字發(fā)生改變的事件
    |typeViewTextSelectionChanged|2000|edittext文字選中發(fā)生改變事件
    |typeViewTextTraversedAtMovementGranularity|20000|UIanimator中在一個視圖文本中進行遍歷會產(chǎn)生這個事件霉涨,多個粒度遍歷文本按价。一般用于語音閱讀context
    |typeWindowContentChanged|800|窗口的內(nèi)容發(fā)生變化惭适,或者更具體的子樹根布局變化事件
    |typeWindowStateChanged|20|新的彈出層導致的窗口變化(dialog、menu俘枫、popupwindow)
    |typeWindowsChanged|400000|屏幕上的窗口變化事件,需要API 21+

  • `accessibilityFeedbackType 此服務(wù)提供的反饋類型

constant value 描述
feedbackAllMask ffffffff 取消所有的可用反饋方式
feedbackAudible 4 可聽見的(非語音反饋)
feedbackGeneric 10 通用反饋
feedbackHaptic 2 觸覺反饋(震動)
feedbackSpoken 1 語音反饋
feedbackVisual 8 視覺反饋
  • accessibilityFlags 輔助功能附加的標志逮走,多個使用 ' | '分隔
constant value 描述
flagDefault 1 默認的配置
flagEnableAccessibilityVolume 80 這個標志要求系統(tǒng)內(nèi)所有的音頻通道鸠蚪,使用由STREAM_ACCESSIBILTY音量控制USAGE_ASSISTANCE_ACCESSIBILITY
flagIncludeNotImportantViews 2 表示可獲取到一些被表示為輔助功能無權(quán)獲取到的view
flagReportViewIds 10 使用該flag表示可獲取到view的ID
flagRequestAccessibilityButton 100 如果輔助功能可用,提供一個輔助功能按鈕在系統(tǒng)的導航欄 API 26+
flagRequestEnhancedWebAccessibility 8 此類擴展的目的是為WebView中呈現(xiàn)的內(nèi)容提供更好的輔助功能支持师溅。這種擴展的一個例子是從一個安全的來源注入JavaScript茅信。如果至少有一個具有此標志的輔助功能服務(wù), 則系統(tǒng)將使能增強的web輔助功能。因此, 清除此標志并不保證該設(shè)備不會使能增強的web輔助功能, 因為可能有另一個使能的服務(wù)在使用它墓臭。
flagRequestFilterKeyEvents 20 能夠監(jiān)聽到系統(tǒng)的物理按鍵
flagRequestFingerprintGestures 200 監(jiān)聽系統(tǒng)的指紋手勢 API 26+
flagRequestTouchExplorationMode 4 系統(tǒng)進入觸控探索模式蘸鲸。出現(xiàn)一個鼠標在用戶的界面
flagRetrieveInteractiveWindows 40 該標志知識的輔助服務(wù)要訪問所有交互式窗口內(nèi)容的系統(tǒng),這個標志沒有被設(shè)置時窿锉,服務(wù)不會收到TYPE_WINDOWS_CHANGE事件酌摇。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嗡载,隨后出現(xiàn)的幾起案子窑多,更是在濱河造成了極大的恐慌,老刑警劉巖洼滚,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埂息,死亡現(xiàn)場離奇詭異,居然都是意外死亡遥巴,警方通過查閱死者的電腦和手機千康,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铲掐,“玉大人拾弃,你說我怎么就攤上這事“诿梗” “怎么了砸彬?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長斯入。 經(jīng)常有香客問我砂碉,道長,這世上最難降的妖魔是什么刻两? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任增蹭,我火速辦了婚禮,結(jié)果婚禮上磅摹,老公的妹妹穿的比我還像新娘滋迈。我一直安慰自己霎奢,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布饼灿。 她就那樣靜靜地躺著幕侠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碍彭。 梳的紋絲不亂的頭發(fā)上晤硕,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音庇忌,去河邊找鬼舞箍。 笑死,一個胖子當著我的面吹牛皆疹,可吹牛的內(nèi)容都是我干的疏橄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼略就,長吁一口氣:“原來是場噩夢啊……” “哼捎迫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起表牢,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤立砸,失蹤者是張志新(化名)和其女友劉穎初茶,沒想到半個月后颗祝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡螺戳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了折汞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡爽待,死狀恐怖损同,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸟款,我是刑警寧澤膏燃,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站何什,受9級特大地震影響组哩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伶贰,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一蛛砰、第九天 我趴在偏房一處隱蔽的房頂上張望黍衙。 院中可真熱鬧泥畅,春花似錦、人聲如沸琅翻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽望迎。三九已至障癌,卻和暖如春凌外,著一層夾襖步出監(jiān)牢的瞬間辩尊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工摄欲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疮薇。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像按咒,于是被迫代替她去往敵國和親迟隅。 傳聞我的和親對象是個殘疾皇子励七,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容