android accessibility
16lz
2022-01-28
主要介绍如开发作符合accessibility规范的应用,和开发自己的accessibility service。 一、 开发作符合accessibility规范的应用( Making Applications Accessible ) 主要有以下三点: 1. Labeling User Interface Elements 这点很简单,如果你都用android自带的控件(像TextView, Button等),大部分事情系统都帮你做了。你只需要在一些没有文字提示的控件(像ImageButton,ImageView,CheckBox等),使用 android:contentDescription属性,增加文字提示内容,如下代码: android:id=”@+id/add_note_button” android:src=”@drawable/add_note” android:contentDescription=”@string/add_note”/> AccessibilityService可以通过调用getContentDescription来获取contentDescription的内容。 2. Enabling Focus Navigation 这点也很简单,就是要保证你所有需要操作的控件,都可以方向键导航来换取焦点。 3. Building Accessible Custom Views 如果使用自定义accessibility控件的话,就需要自己处理accessibility 事件。了解自定义accessibility控件的方法,有助于理解accessibility框架的原理。 自定义accessibility控件主要包含以下4点: (1) Handle directional controller clicks 在获取焦点的View,接收到ok键或回车键的时候,需要执行点击事件的行为。 (2)Implement accessibility API methods 主要有以下四个方法(第4点会更详细介绍): dispatchPopulateAccessibilityEvent() onPopulateAccessibilityEvent() onInitializeAccessibilityEvent() onInitializeAccessibilityNodeInfo()
(3)Send AccessibilityEvent objects specific to your custom view 比如说,在你定制的控件获取焦点的时候,调用View.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)等。
(4)Populate AccessibilityEvent and AccessibilityNodeInfo for your view 构建 AccessibilityEvent和 AccessibilityNodeInfo。这一点比较重要,因为如果我们开发accessibility service的时候,需要用到Accessibility和AccessibilityNodeInfo来获取accessibility 的消息。 先来看看 AccessibilityNodeInfo的构造。 看第(2)点的的四个函数。 onInitializeAccessibilityNodeInfo()用来初始化 AccessibilityNodeInfo。它会根据View的层次填充子View的 AccessibilityNodeInfo和父View的 AccessibilityNodeInfo。比如一个LinearLayout里面放置了两个Button,在回调LinearLayout的 onInitializeAccessibilityNodeInfo()的时候,就会给LinearLayout的 AccessibilityNodeInfo填充上两个子View的 AccessibilityNodeInfo。所以,你可以通过event.getSource()获取到一个和View的层次结构类似的树形 AccessibilityNodeInfo。 再来看看 AccessibilityEvent的构造。看第(2)点第三个函数。 onInitializeAccessibilityEvent()用来初始化AccessibilityEvent的一些属性,如设置className,设置是否被选中等等。可以去看api说明,获取完整的设置属性。除了属性之外,还有一个非常重要的内容,就是accessibility的提示消息。主要通过 dispatchPopulateAccessibilityEvent()和 onPopulateAccessibilityEvent()这两个函数来获取的。看下图: 这是 AccessibilityEvent.getText()的填充过程。getText()返回的是一个字符数组。可以看到,ViewGroup调用dispatchPopulateAccessibilityEvent之后,会触发自身的onPopulateAccessibilityEvent函数。在这个函数里,可以调用event.getText().add(String)的方法来填充数据。接下来就会遍历所有的子View,调用每个子View的 dispatchPopulateAccessibilityEvent方法,然后 dispatchPopulateAccessibilityEvent触发自身的 onPopulateAccessibilityEvent函数。同样, 在这个函数里,可以调用event.getText().add(String)的方法来填充数据。这边有一点要强调一下,ViewGroup和View的AccessibilityEvent是同一个event。这样子,你就可以获取ViewGroup及其所有子View的accessibility消息了。
二、开发自己的accessibility service( Building Accessibility Services ). 主要有以下五点: 1. Manifest Declarations and Permissions 看下面例子:
...
...
...
android:name =". MyAccessibilityService "
android:label ="@string/ accessibility_service_label "
android:permission =" android.permission.BIND_ACCESSIBILITY_SERVICE ">
android:name =" android.accessibilityservice.AccessibilityService " />
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
android:name =" android.permission.BIND_ACCESSIBILITY_SERVICE " />
红色字体是需要添加的权限和intent-filter,绿色字体是配置文件的信息。配置文件看以下例子: xmlns:android ="http://schemas.android.com/apk/res/android"
android:description ="@string/ accessibility_service_description “
4. Getting Event Details 这是在系统回调 onAccessibilityEvent()的时候获取的,主要有两个数据: AccessibilityEvent:在 onAccessibilityEvent()的参数列表里。参照之前自定义accessibility View的章节,调用event.getText()来获取accessibility消息,还可以调用其他方法获取包名类名等消息。具体方法参照文档。 AccessibilityNodeInfo:主要用来遍历View的AccessibilityNodeInfo信息。参考之前自定义accessibility View的章节,调用AccessibilityEvent.getSource()获取当前View的 AccessibilityNodeInfo , 通过 AccessibilityNodeInfo.getChild(index)和 AccessibilityNodeInfo. getParent()获取子View和父View的 AccessibilityNodeInfo。
5. Taking Action for Users accessibility service也可以执行一些操作,如让View获取焦点等,通过调用 AccessibilityNodeInfo. performAction()来实现。也可以执行一些全局的操作,如回到launcher等,通过调用 AccessibilityService.performGlobalAction()来实现。
(3)Send AccessibilityEvent objects specific to your custom view 比如说,在你定制的控件获取焦点的时候,调用View.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)等。
(4)Populate AccessibilityEvent and AccessibilityNodeInfo for your view 构建 AccessibilityEvent和 AccessibilityNodeInfo。这一点比较重要,因为如果我们开发accessibility service的时候,需要用到Accessibility和AccessibilityNodeInfo来获取accessibility 的消息。 先来看看 AccessibilityNodeInfo的构造。 看第(2)点的的四个函数。 onInitializeAccessibilityNodeInfo()用来初始化 AccessibilityNodeInfo。它会根据View的层次填充子View的 AccessibilityNodeInfo和父View的 AccessibilityNodeInfo。比如一个LinearLayout里面放置了两个Button,在回调LinearLayout的 onInitializeAccessibilityNodeInfo()的时候,就会给LinearLayout的 AccessibilityNodeInfo填充上两个子View的 AccessibilityNodeInfo。所以,你可以通过event.getSource()获取到一个和View的层次结构类似的树形 AccessibilityNodeInfo。 再来看看 AccessibilityEvent的构造。看第(2)点第三个函数。 onInitializeAccessibilityEvent()用来初始化AccessibilityEvent的一些属性,如设置className,设置是否被选中等等。可以去看api说明,获取完整的设置属性。除了属性之外,还有一个非常重要的内容,就是accessibility的提示消息。主要通过 dispatchPopulateAccessibilityEvent()和 onPopulateAccessibilityEvent()这两个函数来获取的。看下图: 这是 AccessibilityEvent.getText()的填充过程。getText()返回的是一个字符数组。可以看到,ViewGroup调用dispatchPopulateAccessibilityEvent之后,会触发自身的onPopulateAccessibilityEvent函数。在这个函数里,可以调用event.getText().add(String)的方法来填充数据。接下来就会遍历所有的子View,调用每个子View的 dispatchPopulateAccessibilityEvent方法,然后 dispatchPopulateAccessibilityEvent触发自身的 onPopulateAccessibilityEvent函数。同样, 在这个函数里,可以调用event.getText().add(String)的方法来填充数据。这边有一点要强调一下,ViewGroup和View的AccessibilityEvent是同一个event。这样子,你就可以获取ViewGroup及其所有子View的accessibility消息了。
二、开发自己的accessibility service( Building Accessibility Services ). 主要有以下五点: 1. Manifest Declarations and Permissions 看下面例子:
...
...
...
android:label ="@string/ accessibility_service_label "
android:permission =" android.permission.BIND_ACCESSIBILITY_SERVICE ">
android:resource="@xml/accessibility_service_config" />
android:description ="@string/ accessibility_service_description “
android:canRequestFilterKeyEvents="true"
android:packageNames="com.example.android.apis"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>
4. Getting Event Details 这是在系统回调 onAccessibilityEvent()的时候获取的,主要有两个数据: AccessibilityEvent:在 onAccessibilityEvent()的参数列表里。参照之前自定义accessibility View的章节,调用event.getText()来获取accessibility消息,还可以调用其他方法获取包名类名等消息。具体方法参照文档。 AccessibilityNodeInfo:主要用来遍历View的AccessibilityNodeInfo信息。参考之前自定义accessibility View的章节,调用AccessibilityEvent.getSource()获取当前View的 AccessibilityNodeInfo , 通过 AccessibilityNodeInfo.getChild(index)和 AccessibilityNodeInfo. getParent()获取子View和父View的 AccessibilityNodeInfo。
5. Taking Action for Users accessibility service也可以执行一些操作,如让View获取焦点等,通过调用 AccessibilityNodeInfo. performAction()来实现。也可以执行一些全局的操作,如回到launcher等,通过调用 AccessibilityService.performGlobalAction()来实现。
更多相关文章
- Android(安卓)Studio获取SHA1值
- Android使背景灯(Brightness)高亮的方法
- android中showSoftInput不起作用
- Android的第三个应用---短信发送器
- Android(安卓)程序获取、设置铃声、音量、静音、扬声器
- Android(安卓)NDK 开发教程三:Hello JNI 示例
- Android(java)学习笔记113:Android编写代码调用Vibrator震动功能,按
- 箭头函数的基础使用
- Python技巧匿名函数、回调函数和高阶函数