亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

AccessibilityService(無障礙服務)小結

2019-11-09 13:56:25
字體:
來源:轉載
供稿:網友

https://developer.android.google.cn/guide/topics/ui/accessibility/services.html 無障礙服務,可以監聽界面的操作,比如:點擊、拖動、界面更新等信息。更為強大的是可以獲取屏幕信息,同時具備普通Service的能力。(在別人手機中植入一個無障礙服務并開啟,可以監聽他的手機操作和屏幕信息,eg:獲取微信、QQ當前聊天文字并上傳) 因為無障礙服務相比一般Service過于強大,安裝后還需要在設置->輔助功能中手動開啟。

創建AccessibilityService與聲明

https://developer.android.google.cn/reference/android/accessibilityservice/AccessibilityService.html

創建一個類繼承自AccessibilityService

public class MyAccessibilityService extends AccessibilityService{ @Override PRotected void onServiceConnected() { super.onServiceConnected(); } @Override public void onAccessibilityEvent(AccessibilityEvent event) { } @Override public void onInterrupt() { } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } }

AccessibilityService繼承自普通的Service,因而具備普通Service的生存周期,同時具有自己的一些生命周期。

函數名 描述
onServiceConnected() (可選)當系統成功連接到該AccessibilityService時,將調用此方法。主要用與一次性配置或調整的代碼。
onAccessibilityEvent() (必要)當系統監測到相匹配的AccessibilityEvent事件時,將調用此方法,在整個Service的生命周期中,該方法將被多次調用。
onInterrupt() (必要)系統需要中斷AccessibilityService反饋時,將調用此方法。AccessibilityService反饋包括服務發起的震動、音頻等行為。
onUnbind() (可選)系統要關閉該服務是,將調用此方法。主要用來釋放資源。

AccessibilityService服務聲明

和普通Service一樣,AccessibilityService同樣需要在Manifest.xml中注冊。

<service android:name=".MyAccessibilityService" android:label="@string/accessibility_service_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/accessibility_service_config" /></service>

android.permission.BIND_ACCESSIBILITY_SERVICE權限和action是必須的。 同時AccessibilityService需要提供設置列表(meta-data),該設置也可以在運行時通過AccessibilityService.setServiceInfo (AccessibilityServiceInfo info)進行動態設置。不過該方式并不能設置所有的參數,因而推薦的方法為(meta-data)。 android:resource中的地址為:/res/xml/accessibility_service_config.xml。

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:descr各項參數參考AccessibilityServiceInfo。

AccessibilityServiceInfo 配置類

https://developer.android.google.cn/reference/android/accessibilityservice/AccessibilityServiceInfo.html AccessibilityService的配置類,可使用setService進行動態設置,同時和上述的accessibility_service_config.xml相對應。 以下參數可以使用“|”表示使用多個選項。

android:accessibilityEventTypes 事件類型

AccessibilityService服務響應的事件類型,只有聲明了的類型,系統才會調用該服務的onAccessibilityEvent。

常量 描述
typeViewClicked 點擊事件
typeViewSelected view被選擇
typeViewScrolled 滑動事件
typeWindowContentChanged 窗口內容該表
typeAllMask 所有事件

完整列表如下: typeViewClicked typeViewLongClicked typeViewSelected typeViewFocused typeViewTextChanged typeWindowStateChanged typeNotificationStateChanged typeViewHoverEnter typeViewHoverExit typeTouchExplorationGestureStart typeTouchExplorationGestureEnd typeWindowContentChanged typeViewScrolled typeViewTextSelectionChanged typeAnnouncement typeViewAccessibilityFocused typeViewAccessibilityFocusCleared typeViewTextTraversedAtMovementGranularity typeGestureDetectionStart typeGestureDetectionEnd typeTouchInteractionStart typeTouchInteractionEnd typeWindowsChanged typeContextClicked typeAssistReadingContext typeAllMask

android:accessibilityFeedbackType 反饋類型

AccessibilityService服務的反饋類型。

常量 描述
feedbackSpoken 語音反饋
feedbackHaptic 觸覺(震動)反饋
feedbackAudible 音頻反饋
feedbackVisual 視頻反饋
feedbackGeneric 通用反饋
feedbackAllMask 以上都具有

android:accessibilityFlags 額外聲明

一些格外的參數。

常量 描述
flagDefault 默認
flagIncludeNotImportantViews
flagRequestTouchExplorationMode
flagRequestEnhancedWebAccessibility
flagReportViewIds 允許獲得view id,需要獲取viewid的時候需要該參數,開始沒聲明導致nodeInfo. getViewIdResourceName()返回的為null
flagRequestFilterKeyEvents
flagRetrieveInteractiveWindows 允許獲得windows,使用getWindows時需要該參數,否則會返回空列表

其他可設置參數

參數名 描述
android:canRetrieveWindowContent 設置為“true”表示允許獲取屏幕信息,使用getWindows、getRootInActiveWindow等函數時需要為“true”
android:packageNames 服務響應的事件來源,若設置,則服務只能獲取該package發出的事件,不設置可獲得所有的事件源
android:notificationTimeout 同一種事件類型觸發的最短時間間隔(毫秒)
android:description 服務和行為的簡短描述

AccessibilityEvent 事件類

https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityEvent.html 常用實例化途徑:在MyAccessibilityService 中 onAccessibilityEvent(AccessibilityEvent event) 獲得該實例,表示監聽事件觸發。

返回值 方法 描述
int getEventType() 獲取事件類型(點擊等)
CharSequence getPackageName() 時間來源包名
String toString() 打印事件

AccessibilityNodeInfo 結點類

https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityNodeInfo.html 常用實例化途徑:AccessibilityService.getRootInActiveWindow()獲得(當前活動窗口的根節點)。AccessibilityWindowInfo類也能獲取該window下的node。 該類與下圖有對應關系(通過uiautomatorviewer工具獲得): image 常用方法:

返回值 方法 描述
List findAccessibilityNodeInfosByText(String text) 通過text尋找子節點
List findAccessibilityNodeInfosByViewId(String viewId) 通過id查找子節點
CharSequence getPackageName() Gets the package this node comes from.
AccessibilityNodeInfo getParent() Gets the parent.
AccessibilityNodeInfo getChild(int index) Get the child at given index.
int getChildCount() Gets the number of children.
CharSequence getText() Gets the text of this node.
String getViewIdResourceName() Gets the fully qualified resource name of the source view’s id.
AccessibilityWindowInfo getWindow() Gets the window to which this node belongs.
boolean isChecked() Gets whether this node is checked.
String toString() Returns a string representation of the object.

比如: 遍歷打印當前布局信息可以使用一下代碼(布局節點樹)

@Override public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) { if(accessibilityEvent.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED){ AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); dfsnode(nodeInfo,0); } } public void dfsnode(AccessibilityNodeInfo node , int num){ StringBuilder stringBuilder = new StringBuilder(); for(int i = 0 ;i < num ; i++){ stringBuilder.append("__ "); //父子節點之間的縮進 } Log.i("####",stringBuilder.toString() + node.toString()); //打印 for(int i = 0 ; i < node.getChildCount() ; i++){ //遍歷子節點 dfsnode(node.getChild(i),num+1); } }

AccessibilityWindowInfo 窗口類

https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityWindowInfo.html 常用實例化途徑:AccessibilityService.getWindows()獲得,返回值是一個list列表。

返回值 方法 描述
AccessibilityNodeInfo getRoot() 獲得該窗口的根節點信息
AccessibilityWindowInfo getChild(int index) Gets the child window at a given index.
int getChildCount() Gets the number of child windows.
int getId() Gets the unique window id.
boolean isActive() Gets if this window is active.
boolean isFocused() Gets if this window has input focus.

綜合應用,搶紅包插件

代碼來自涅槃1992:http://www.jianshu.com/p/4cd8c109cdfb 配置代碼:

<?xml version="1.0" encoding="utf-8"?><accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged| typeWindowContentChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:notificationTimeout="100" android:packageNames="com.tencent.mm" />

Service代碼:

public class RobService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); switch (eventType) { case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: handleNotification(event); break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: String className = event.getClassName().toString(); if (className.equals("com.tencent.mm.ui.LauncherUI")) { getPacket(); } else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) { openPacket(); } else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")) { close(); } break; } } /** * 處理通知欄信息 * * 如果是微信紅包的提示信息,則模擬點擊 * * @param event */ private void handleNotification(AccessibilityEvent event) { List<CharSequence> texts = event.getText(); if (!texts.isEmpty()) { for (CharSequence text : texts) { String content = text.toString(); //如果微信紅包的提示信息,則模擬點擊進入相應的聊天窗口 if (content.contains("[微信紅包]")) { if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) { Notification notification = (Notification) event.getParcelableData(); PendingIntent pendingIntent = notification.contentIntent; try { pendingIntent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } } } } } } /** * 關閉紅包詳情界面,實現自動返回聊天窗口 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void close() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { //為了演示,直接查看了關閉按鈕的id List<AccessibilityNodeInfo> infos = nodeInfo.findAccessibilityNodeInfosByViewId("@id/ez"); nodeInfo.recycle(); for (AccessibilityNodeInfo item : infos) { item.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } /** * 模擬點擊,拆開紅包 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void openPacket() { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { //為了演示,直接查看了紅包控件的id List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("@id/b9m"); nodeInfo.recycle(); for (AccessibilityNodeInfo item : list) { item.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } /** * 模擬點擊,打開搶紅包界面 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void getPacket() { AccessibilityNodeInfo rootNode = getRootInActiveWindow(); AccessibilityNodeInfo node = recycle(rootNode); node.performAction(AccessibilityNodeInfo.ACTION_CLICK); AccessibilityNodeInfo parent = node.getParent(); while (parent != null) { if (parent.isClickable()) { parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); break; } parent = parent.getParent(); } } /** * 遞歸查找當前聊天窗口中的紅包信息 * * 聊天窗口中的紅包都存在"領取紅包"一詞,因此可根據該詞查找紅包 * * @param node */ public AccessibilityNodeInfo recycle(AccessibilityNodeInfo node) { if (node.getChildCount() == 0) { if (node.getText() != null) { if ("領取紅包".equals(node.getText().toString())) { return node; } } } else { for (int i = 0; i < node.getChildCount(); i++) { if (node.getChild(i) != null) { recycle(node.getChild(i)); } } } return node; } @Override public void onInterrupt() { } @Override protected void onServiceConnected() { super.onServiceConnected(); }}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩成人av一区| 性欧美xxxx交| 日日摸夜夜添一区| 国产视频在线一区二区| 日韩网站免费观看高清| 亚洲精品白浆高清久久久久久| 国产成人精品免高潮费视频| 成人免费在线视频网站| 日韩三级影视基地| 亚洲国产日韩欧美在线图片| 国产精品高潮视频| 色综合老司机第九色激情| 国产精品久久久久影院日本| 亚洲免费成人av电影| 欧美精品999| 久久天天躁夜夜躁狠狠躁2022| 久久免费视频在线| 国产精品视频永久免费播放| 国产精品wwww| 国产成人精品国内自产拍免费看| 国产精品久久久亚洲| 国产亚洲精品久久| 亚洲国产天堂久久综合| 国产精品视频一区二区高潮| 国产有码一区二区| 97在线视频观看| 大胆欧美人体视频| 疯狂做受xxxx高潮欧美日本| 国产精品网站大全| 成人国产精品久久久| 国产精品第二页| 欧美精品在线观看91| 国产精品日日摸夜夜添夜夜av| 91情侣偷在线精品国产| 欧美日韩在线第一页| 欧美老少做受xxxx高潮| 国产97在线视频| 91精品免费视频| 九九热精品视频在线播放| 国产精品久久久久久av福利软件| 亚洲桃花岛网站| 亚洲精品丝袜日韩| 欧美尤物巨大精品爽| 亚洲欧美中文字幕在线一区| 欧美中文字幕在线观看| 国产精品视频一区二区高潮| 福利微拍一区二区| 久久久精品视频在线观看| 国产精品人人做人人爽| 日韩一区二区欧美| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲综合社区网| 中文字幕在线看视频国产欧美在线看完整| 亚洲片国产一区一级在线观看| 亚洲黄色有码视频| 欧美精品18videos性欧| 亚洲欧美国产高清va在线播| 最近2019年中文视频免费在线观看| 欧美黄色免费网站| 国产成人欧美在线观看| 国模gogo一区二区大胆私拍| 久久精品视频中文字幕| 久久精品一区中文字幕| 欧美中文在线观看国产| 日韩欧美亚洲综合| 亚洲永久在线观看| 在线观看中文字幕亚洲| 国产精品中文久久久久久久| 亚洲伊人成综合成人网| 亚洲精品在线视频| 久久久国产一区二区| 欧美激情2020午夜免费观看| 国产精品国模在线| 91国产一区在线| 亚洲欧美在线一区| 国产丝袜一区视频在线观看| 国产精品mp4| 亚洲无线码在线一区观看| 黑人巨大精品欧美一区二区免费| 欧美激情一级精品国产| 97av在线影院| 欧美裸身视频免费观看| 国产成人午夜视频网址| 国产噜噜噜噜噜久久久久久久久| 久久精品2019中文字幕| 日韩黄色高清视频| 国产日韩欧美在线播放| 亚洲人成77777在线观看网| 欧美夫妻性生活视频| 俺也去精品视频在线观看| 超碰日本道色综合久久综合| 一区二区亚洲欧洲国产日韩| 国产精品高潮呻吟久久av野狼| 日韩视频免费在线观看| 日韩黄在线观看| 午夜精品久久久久久久99黑人| 国产一区二区三区在线视频| 日韩成人在线视频| 日韩精品在线视频| 日韩一区二区久久久| 欧美成人精品在线视频| 亚洲国产欧美日韩精品| 亚洲永久在线观看| 亚洲第一区第二区| 亚洲天堂精品在线| 91av在线影院| 日韩欧美在线第一页| 国产精品xxx视频| 久久青草精品视频免费观看| 亚洲r级在线观看| 国产三级精品网站| 青青青国产精品一区二区| 亚洲综合小说区| 国内免费久久久久久久久久久| 欧美制服第一页| 国产精品免费一区| 日韩在线播放av| 国产精品av网站| 精品无人国产偷自产在线| 精品国产欧美成人夜夜嗨| 亲爱的老师9免费观看全集电视剧| 国产精品日韩精品| 91色在线观看| 精品美女国产在线| 国产精品亚洲欧美导航| 91久久久亚洲精品| 亚洲天堂免费视频| 久久精品在线视频| 九九九久久国产免费| 国产成人一区二区三区小说| 亚洲白拍色综合图区| 久久精品国产电影| 亚洲国产中文字幕在线观看| 亚洲高清免费观看高清完整版| 91精品国产乱码久久久久久久久| 91在线|亚洲| 97国产一区二区精品久久呦| 国产欧洲精品视频| 高清日韩电视剧大全免费播放在线观看| 亚洲色图国产精品| 欧美激情在线播放| 亚洲天堂av综合网| 欧美亚洲国产另类| 大胆人体色综合| 国产在线不卡精品| 欧美激情亚洲综合一区| 国产精品777| 欧美激情视频网址| 伊人久久精品视频| 国产日韩欧美中文在线播放| 国产精品国产福利国产秒拍| 欧美大片欧美激情性色a∨久久| 欧美性生交xxxxxdddd| 日本亚洲精品在线观看| 亚洲午夜未删减在线观看| 日韩欧美在线一区| 97视频在线看| 国产欧美日韩免费看aⅴ视频| 亚洲精品永久免费精品| 日韩av免费在线观看| 国产视频精品久久久| 亚洲第一国产精品| 中文字幕精品在线视频| 1769国内精品视频在线播放|