0x00什麼是Accessibility(輔助功能) 考慮到部分用戶不能很好地使用Android設備,比如由於視力、身體、年齡方面的限制,造成閱讀內容、觸控操作、聲音信息等方面的獲取困難,Android提供了Accessibility特性和服務幫助用戶更好地使用Android設備。 依據Androi ...
0x00什麼是Accessibility(輔助功能)
考慮到部分用戶不能很好地使用Android設備,比如由於視力、身體、年齡方面的限制,造成閱讀內容、觸控操作、聲音信息等方面的獲取困難,Android提供了Accessibility特性和服務幫助用戶更好地使用Android設備。
依據Android官方的詳細介紹,開發者在增加視圖屬性如contentDescription等內容後,可以在不修改原有代碼邏輯的情況下使用戶體驗得到優化,如預裝在Android 設備上的屏幕閱讀器TalkBack,在沒有修改系統源碼的情況下,滿足了視力不足的用戶使用Android設備的需求,TalkBack會使用語音反饋描述用戶所執行的操作,以及告知用戶收到的提醒和通知,可以幫助視力水平較低的用戶順利進行手機的觸控、閱讀內容的進行。
0x01如何使用Accessibility(輔助功能)
在項目中應用AccessibilityService的三個步驟:
①繼承AccessibilibityService,實現onAccessibilityEvent()和onInterrupt()方法。
在onAccessibilityEvent()方法中,我們可以接收所監聽的事件。
②新建配置文件
在res目錄下新建xml文件夾,新建accessibility.xml文件,如下所示:
欄位名 |
欄位說明 |
指明瞭自己的輔助服務關心哪些應用發出的事件,多個應用包名之間用逗號分隔,如果不填,則關註手機上所有應用發出的事件。例如我們現在要利用輔助點擊做app的自動安裝功能,那麼只需要關註 com.android.packageinstaller這個包發出的事件。如果只關註微信發出的事件,則這裡填com.tencent.mm。 |
|
輔助服務關註的事件類型,例如TYPE_VIEW_FOCUSED,TYPE_WINDOW_STATE_CHANGED,TYPE_NOTIFICATION_STATE_CHANGED等等。如果只關心微信的通知欄,那麼這個屬性可以設置為TYPE_NOTIFICATION_STATE_CHANGED。 |
|
輔助服務額外的flag信息。例如FLAG_REPORT_VIEW_IDS可以使回調的事件帶上view的ID。 |
|
事件的反饋類型,例如聲音反饋、觸覺反饋、視覺反饋等。 |
|
兩個同樣類型的輔助事件發給輔助服務的最小時間間隔 |
|
是否可以獲取視窗內容 |
③在AndroidMainifest中註冊:
該service需要許可權android.permission.BIND_ACCESSIBILITY_SERVICE和action:android.accessibilityservice.AccessibilityService,使用名為android.accessibilityservice的meta-data指定配置文件。
重要參數及方法:
①AccessibilityEvent:
TYPE_NOTIFICATION_STATE_CHANGED:通知欄狀態變化
TYPE_VIEW_CLICKED:視圖被點擊
TYPE_WINDOW_CONTENT_CHANGED:視窗內容變化
TYPE_WINDOW_STATE_CHANGED:視窗狀態變化
....
②AccessibilityService:
onServiceConnected() :可選。系統會在成功連接上你的服務的時候調用這個方法,在這個方法里你可以做一下初始化工作,例如設備的聲音震動管理,也可以調用setServiceInfo()進行配置AccessibilityServiceInfo。
onAccessibilityEvent() :必須。通過這個函數可以接收系統發送來的AccessibilityEvent,接收來的AccessibilityEvent是經過過濾的,過濾是在配置工作時設置的。
onInterrupt() :必須。這個在系統想要中斷AccessibilityService返給的響應時會調用。在整個生命周期里會被調用多次。
onUnbind() :可選。在系統將要關閉這個AccessibilityService會被調用。在這個方法中進行一些釋放資源的工作。
getRootInActiveWindow():獲取當前活動視窗中的根節點。
performGlobalAction():執行全局動作,例如返回等操作。
...
③AccessibilityNodeInfo:
getParent():獲取父節點。
getChild():獲取子節點。
performAction():在節點上執行一個動作。
findAccessibilityNodeInfosByText():通過字元串查找節點元素。
findAccessibilityNodeInfosByViewId():通過視圖id查找節點元素。
...
0x02 Accessibility(輔助功能)應用實例
AccessibilityService一般應用步驟
①分析操作的流程,拆解成單步可實現的過程;
②通過UIAutomator和adb shell dumpsys來查看對應的UI控制項ID、文本或者是具體的Activity;
③通過邏輯組合進行代碼編寫;
④調試、相容性處理。
實例1.免root自動安裝
實例2.微信自動搶紅包(僅供技術交流)
①流程拆分(通知欄觸發)
第一步:當通知欄變化時,檢測是否包含“[微信紅包]”關鍵字,若包含,則觸發這個通知消息包含的intent。
第二步:跳轉到聊天頁面(com.tencent.mm.ui.LauncherUI),根據關鍵字“領取紅包”占到對應的view,模擬點擊觸發ACTION_CLICK點擊事件。
第三步:跳轉到開紅包界面(com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI),根據開紅包按鈕的id:com.tencent.mm:id/bg7模擬點擊觸發ACTION_CLICK點擊事件。
第四步:進入紅包詳情頁面(com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI),
根據返回鍵的id:com.tencent.mm:id/gd模擬點擊觸發ACTION_CLICK點擊事件。
②微信UI結構
涉及微信界面的類:
l 微信主界面或聊天界面 -- com.tencent.mm.ui.LauncherUI
l 開紅包界-- com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI
l 紅包詳情 -- com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI
相關控制項ID:
l “開”按鈕:com.tencent.mm:id/bg7
l 紅包詳情頁返回按鈕:com.tencent.mm:id/gd
③具體代碼實現:
(1)重寫MyAccessibilityService中的onAccessibilityEvent方法,監聽通知欄消息,判斷消息中是否“[微信紅包]”,若包含,則跳轉到對應的聊天界面。
(2)onAccessibilityEvent方法中的第二個case,監聽com.tencent.mm.ui.LauncherUI,com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI,com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI三個界面,分別進行點擊最近收到的紅包,拆紅包,推出紅包詳情頁面的操作。
(3)遍歷所有節點,獲取最近收到的紅包,進行模擬點擊。
(4)根據控制項ID對相應的view進行模擬點擊,領取紅包。
0x03 延伸閱讀
Android Accessibility 安全性研究報告
http://www.freebuf.com/articles/terminal/114045.html
0x04 參考
Building Accessibility Services
https://developer.android.com/guide/topics/ui/accessibility/services.html
AccessibilityService從入門到出軌
http://mp.weixin.qq.com/s/7L2ysyTlFR1Xz4tk73dxuA
管家在手,紅包我有 —手機管家紅包提醒原理揭秘
http://km.oa.com/group/16523/articles/show/256070?kmref=search&from_page=1&no=1