浅谈辅助功能 AccessibilityService
来源:互联网 发布:linux 该文件夹名字 编辑:程序博客网 时间:2024/04/28 03:38
辅助功能定义
对于那些由于视力、听力或其它身体原因导致不能方便使用Android智能手机的用户,Android提供了Accessibility功能和服务帮助这些用户更加简单地操作设备,包括文字转语音(不支持中文)、触觉反馈、手势操作、轨迹球和手柄操作。开发者可以搭建自己的Accessibility服务,这可以加强可用性,例如声音提示,物理反馈,和其他可选的操作模式。
随着Android版本的不断升级,AndroidAccessibility功能也越来越强大,Android 4.0版本以前,系统辅助服务功能比较单一,仅仅能过单向获取窗口元素信息,比如获取输入框用户输入内容。到Android 4.1版本以后,系统辅助服务增加了与窗口元素的双向交互,此时可以通过辅助功能服务操作窗口元素,比如点击按钮等。
现实辅助功能准备工作
1、新建自己的AccessibilityService类
想要让自己程序实辅助功能,首先第一步就是要新建类并继承AccessibilityService类。继承自AccessibilityService的子类里实现几个重要的重载方法:
方法
描述
onAccessibilityEvent()
必须。通过这个函数可以接收系统发送来的AccessibilityEvent,接收来的AccessibilityEvent是经过过滤的,过滤是在配置工作时设置的。
onInterrupt()
必须。这个在系统想要中断AccessibilityService返给的响应时会调用。在整个生命周期里会被调用多次。
onServiceConnected()
可选。在系统成功连接上这个AccessibilityService会调用。在这个方法里你可以做一下初始化工作。
onUnbind()
可选。在系统将要关闭这个AccessibilityService会被调用。在这个方法中进行一些释放资源的工作。
2、新建AccessibilityService配置文件
<?xml version="1.0" encoding="utf-8"?><accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/XXXXX" android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackGeneric" android:notificationTimeout="100" android:accessibilityFlags="flagDefault" android:packageNames="XXXXX" android:canRetrieveWindowContent="true" android:settingsActivity = "XXXXX"/>
属性分别代表意义:
属性
描述
description
就是设置里辅助功能项的备注说明(不可在运行时修改)。
accessibilityEventTypes
设置响应事件的类型,typeAllMask当然就是响应所有类型的事件了。当然还有单击、长按、滑动等(多个值由“|”分隔)(可在运行时修改)。
值有:
值
说明
typeViewClicked
Receives TYPE_VIEW_CLICKED events.
typeViewLongClicked
Receives TYPE_VIEW_LONG_CLICKED events.
typeViewSelected
Receives TYPE_VIEW_SELECTED events.
typeViewFocused
Receives TYPE_VIEW_FOCUSED events.
typeViewTextChanged
Receives TYPE_VIEW_TEXT_CHANGED events.
typeWindowStateChanged
Receives TYPE_WINDOW_STATE_CHANGED events.
typeNotificationStateChanged
Receives TYPE_NOTIFICATION_STATE_CHANGED events.
typeViewHoverEnter
Receives TYPE_VIEW_HOVER_ENTER events.
typeViewHoverExit
Receives TYPE_VIEW_HOVER_EXIT events.
typeTouchExplorationGestureStart
Receives TYPE_TOUCH_EXPLORATION_GESTURE_START events.
typeTouchExplorationGestureEnd
Receives TYPE_TOUCH_EXPLORATION_GESTURE_END events.
typeWindowContentChanged
Receives TYPE_WINDOW_CONTENT_CHANGED events.
typeViewScrolled
Receives TYPE_VIEW_SCROLLED events.
typeViewTextSelectionChanged
Receives TYPE_VIEW_TEXT_SELECTION_CHANGED events.
typeAnnouncement
Receives TYPE_ANNOUNCEMENT events.
typeViewAccessibilityFocused
Receives TYPE_VIEW_ACCESSIBILITY_FOCUSED events.
typeViewAccessibilityFocusCleared
Receives TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED events.
typeViewTextTraversedAtMovementGranularity
Receives TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY events.
typeGestureDetectionStart
Receives TYPE_GESTURE_DETECTION_START events.
typeGestureDetectionEnd
Receives TYPE_GESTURE_DETECTION_END events.
typeTouchInteractionStart
Receives TYPE_TOUCH_INTERACTION_START events.
typeTouchInteractionEnd
Receives TYPE_TOUCH_INTERACTION_END events.
typeWindowsChanged
Receives TYPE_WINDOWS_CHANGED events.
typeContextClicked
Receives TYPE_VIEW_CONTEXT_CLICKED events.
typeAssistReadingContext
Receives TYPE_ASSIST_READING_CONTEXT events.
typeAllMask
Receives TYPES_ALL_MASK i.e. all events.
accessibilityFeedbackType
设置回馈给用户的方式,有语音播出和振动(多个值由“|”分隔)(可在运行时修改)。
值有:
值
说明
feedbackSpoken
Provides FEEDBACK_SPOKEN feedback.
feedbackHaptic
Provides FEEDBACK_HAPTIC feedback.
feedbackAudible
Provides FEEDBACK_AUDIBLE feedback.
feedbackVisual
Provides FEEDBACK_VISUAL feedback.
feedbackGeneric
Provides FEEDBACK_GENERIC feedback.
feedbackAllMask
Provides FEEDBACK_ALL_MASK feedback.
notificationTimeout
相同类型的两个事件之间的最小时间发送到该服务(可在运行时修改)。
accessibilityFlags
可访问性(多个值由“|”分隔)(可在运行时修改)。
值有:
值
说明
flagDefault
Has flag DEFAULT
flagIncludeNotImportantViews
Has flag FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
flagRequestTouchExplorationMode
Has flag FLAG_REQUEST_TOUCH_EXPLORATION_MODE
flagRequestEnhancedWebAccessibility
Has flag FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
flagReportViewIds
Has flag FLAG_REPORT_VIEW_IDS
flagRequestFilterKeyEvents
Has flag FLAG_REQUEST_FILTER_KEY_EVENTS
flagRetrieveInteractiveWindows
Has flag FLAG_RETRIEVE_INTERACTIVE_WINDOWS
packageNames
响应的程序的包名(多个值由“,”分隔)(可在运行时修改)。
canRetrieveWindowContent
是否能够检索活动窗口的内容(不可在运行时修改)。
settingsActivity
允许用户修改此服务的设置的活动组件名称,(如果不需要在运行时修改设置,可忽略该项)(不可在运行时修改)。
修改设置,可使用:android.accessibilityservice.AccessibilityService.setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo).
3、AndroidManifest里注册服务
AndroidManifest.XML文件添加以下配置
<service android:label="@string/XXXXX"// XXXXX就是设置里辅助功能项的标题 android:name=".XXXXX"// XXXXX为自定义的类 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/XXXXX" />// XXXXX为上面新建的配置XML文件</service>
获取UI元素
在onAccessibilityEvent中,使用参数event的getSource方法获取到的AccessibilityNodeInfo实例,即为触发这次事件的UI节点。获取到当前界面UITree的根节点可以使用findAccessibilityNodeInfosByText或者findAccessibilityNodeInfosByViewId方法。需要注意findAccessibilityNodeInfosByText在获取UI元素时的判断逻辑是包含而非等于。
示例代码如:
List<AccessibilityNodeInfo>nodes = event.getSource().findAccessibilityNodeInfosByText("立即安装");List<AccessibilityNodeInfo>nodes = event.getSource().findAccessibilityNodeInfosByViewId("txt_1");
模拟用户操作
模拟点击
获取界面上UI元素之后,可根据元素是否可响应操作进行相应的处理。例如,如果UI元素是一个有效的按钮,则可以使用下面的代码来进行模拟点击:
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
同理,如果UI元素是一个有效的列表,则可以使用下面的代码进行模拟滑动:
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
模拟物理键
也可以模拟物理键的操作,例如模拟按下返回键的代码是:
AccessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
模拟打开消息通知栏
在上面介绍accessibilityEventTypes中提到有一个事件: typeNotificationStateChanged,它便是消息通知栏状态发生改变变触发。一些红包外挂工具里头,一有红包就提醒的原理便是在onAccessibilityEvent中监听该事件,然后判断关键字并打开通知,示例关键代码如:
if(event.getEventType() != AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED){ return;}List<CharSequence>texts = event.getText();if(texts.size() <= 0 || !mAutoTrack) { return;}for(CharSequence text : texts) { String content = text.toString(); if(!content.contains("[微信红包]")){ continue; } if(event.getParcelableData() == null || !(event.getParcelableData() instanceofNotification)) { continue; } Notification notification = (Notification)event.getParcelableData(); PendingIntent pendingIntent =notification.contentIntent; try{ pendingIntent.send(); }catch (PendingIntent.CanceledException e) { e.printStackTrace(); }}
语音播放
首先,定义一个TextToSpeech对象,并在服务连上后进行初始化,示例代码如:
private TextToSpeech mTts; ……mTts = newTextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { mTts.setLanguage(Locale.US); } }});
执行语音播放代码:
mTts.speak("hello",TextToSpeech.QUEUE_FLUSH, null);
最后别忘记释放资源:
mTts.shutdown();
建议:
在开发APP想支持语音播功能时,建议在用户界面控件中,通过使用android:contentDescription属性来描控件特性。
对于EditText控件,提供了一个android:hint属性代替了contentDescription属性
判断是否开启辅助功能
intaccessibilityEnabled =Settings.Secure.getInt(context.getApplicationContext().getContentResolver(),android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);if(accessibilityEnabled == 1) { String settingValue =Settings.Secure.getString(context.getApplicationContext().getContentResolver(),Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);}
如果手机中开启了一些APP的辅助功能,settingValue的值为:APP1包名/APP1继承AccessibilityService类全名: APP2包名/APP2继承AccessibilityService类全名
使用Dump View Hierarchy for UI Automator解析UI界面视图帮助查找节点对象
一、
二、
三、
- 浅谈辅助功能 AccessibilityService
- 浅谈辅助功能 AccessibilityService
- (AccessibilityService) Android 辅助功能笔记
- Android辅助功能服务AccessibilityService
- AccessibilityService之微信抢红包辅助功能实现
- Android辅助功能AccessibilityService与抢红包辅助
- Android辅助功能AccessibilityService与抢红包辅助
- Android 无障碍辅助功能AccessibilityService(1)
- Android 无障碍辅助功能AccessibilityService(2)
- AccessibilityService 开启辅助功能后,导致手机需要双击生效
- Android辅助功能原理与基本使用详解-AccessibilityService
- API Demos(6) AccessibilityService 无障碍辅助功能
- 辅助服务类:AccessibilityService使用
- Android系统学习-android.accessibilityservice(辅助服务)
- Accessibilityservice(辅助服务开发)学习笔记
- Android AccessibilityService(辅助服务)学习
- AccessibilityService 一个类似辅助的类
- AccessibilityService辅助类用法(Android 中的另类钩子)
- mysql 5.7.14 在 windows 下的配置
- Windows7环境下MyEclipse+Nutch2.2.1+Mysql搭建
- PIQ19: Longest Common Substring
- 关于mysql下索引使用的一点心得
- Ajax传值的初级学习
- 浅谈辅助功能 AccessibilityService
- Genymotion出现Unable to load VirtualBox engine
- RasEntryDlg
- 一些优秀的github开源项目
- LA 7339 Owllen(贪心)
- 秒杀系统架构分析与实战
- Failed to stop the muxer
- ScrollView中设置ListView的高度的方法
- 沉浸式状态栏(变色状态栏、透明状态栏)的实现