Android 无障碍辅助功能AccessibilityService(1)

构建无障碍服务

[[ http://developer.android.com/guide/topics/ui/accessibility/services.html | (原文地址)]](需翻墙),本文中的超链接使用的是该[[ http://android-doc.com/guide/topics/ui/accessibility/services.html| 地址 ]]下的

一个无障碍服务是一个应用程序,这个程序提供了增强的用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们。例如,正在驾驶的用户,正照顾小孩子或参加一个非常常闹的聚会,可能需要额外的或替代的接口反馈。
Android提供了标准的无障碍服务,包括TalkBack,开发人员可以创建和分配自己的服务。该文档解释了创建无障碍服务的基本内容。
对你来讲,在Android 1.6(API4)中引入构建和部署的无障碍服务在Android 4.0(API级别14)中做了显著的改善。 Android Support Library也对Android 4.0这些增强的无障碍,Android 1.6以上版本,进行了更新,提供支持。鼓励开发人员的目标是使用Support Library,在Android 4.0介绍的更先进的无障碍特性上进行兼容无障碍服务的开发。

Manifest 声明和权限


提供无障碍服务的应用程序必须在其应用的manifests中当作Android系统的一个无障碍服务进行声明。本节解释了无障碍服务中必需和可选设置。

无障碍服务声明

要将其作为一个无障碍服务,在应用程序的Manifest中,必须包括service元素(而不是activity元素)。此外,在service元素中,还必须包括一个无障碍服务的intent filter。为了与Android 4.1以上版本的兼容性,manifest中需要指定BIND_ACCESSIBILITY_SERVICE 权限,以下示例:

<application>  
  <service android:name=".MyAccessibilityService"  
      android:label="@string/accessibility_service_label">  
    <intent-filter>  
      <action android:name="android.accessibilityservice.AccessibilityService" />  
    </intent-filter>  
  </service>  
  <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />  
</application> 

这些声明的所有无障碍服务需要部署在Android 1.6(API级别4)以上。

无障碍服务配置

无障碍服务还必须提供一个指定无障碍服务处理事件的类型的配置和额外的信息服务。一个无障碍服务的配置被包含在[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityServiceInfo.html| AccessibilityServiceInfo ]]类中。你的服务可以使用这个类的一个实例,在运行时[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)| setserviceinfo() ]]来构建和设置一个配置。然而,并非所有的配置选项可以使用这种方法。

从Android 4.0,您可以在你的mainifest中包含一个元素引用一个配置文件,它允许您为您的无障碍服务设置整个范围的选项,如下例所示:

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

这个 meta-data元素指的是在应用程序的资源目录创建的一个XML文件。(/res/xml/accessibility_service_config.xml). 下面的代码显示了服务配置文件的示例内容:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    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"
/>

更多用于无障碍服务配置文件的XML属性的信息,请按照以下链接到参考文档:

注册无障碍事件

无障碍服务配置参数的最重要的一个功能是允许您指定哪些类型的无障碍事件你的服务可以处理。通过指定这个信息能够是无障碍服务相互配合,并让作为一个开发者的你灵活地处理特定的应用程序的特定事件类型。事件过滤包括下列标准:

  • Package Names ——指定你想要处理的无障碍服务的应用程序的包名。如果省略该参数,你的无障碍服务被认为是对于任何应用程序的无障碍的事件提供服务。这个参数可以在无障碍服务配置文件中,android:packageNames属性来设置,这个属性用逗号分隔多个包名,或者使用AccessibilityServiceInfo.packageNames 设置。
  • Event Types ——指定你想要你的服务来处理的无障碍活动的类型。这个参数可以设置在无障碍服务配置文件中,使用android:accessibilityEventTypes属性,用|分隔的字符(例如accessibilityEventTypes = ” typeViewClicked | typeViewFocused”),或使用AccessibilityServiceInfo.eventTypes 设置。

    当设置无障碍服务,仔细考虑哪些事件你的服务是能够处理,只注册这些事件。因为用户可以激活超过一个无障碍服务,服务必须不使用它是不能够处理事件。记住,其他服务可能会处理这些事件是为了改善用户的体验。

注意:,如果服务提供不同的反馈类型,Android框架分派无障碍事件给多个无障碍服务。然而,如果两个或多个服务提供相同的反馈类型,那么只有第一个注册服务接收事件。

无障碍服务方法

一个无障碍服务必须继承[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html | accessibilityservice ]],并且重写这个类中下面的方法。这些方法由Android系统按顺序调用的,当服务开启时 ([[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#onServiceConnected() | onserviceconnected() ]]),当服务运行时([[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#onAccessibilityEvent(android.view.accessibility.AccessibilityEvent)| onaccessibilityevent() ]],[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#onInterrupt()| oninterrupt( )]]),当服务结束时([[ http://android-doc.com/reference/android/app/Service.html#onUnbind(android.content.Intent)| onunbind() ]])。

获取事件的注意事项

Android系统通过AccessibilityEvent对象提供用户界面交互的无障碍服务的信息。Android 4.0之前,一些有效的信息是放在无障碍事件中的,同时提供了大量的用户选择用户界面控件的细节,及有限的上下文信息。在许多情况下,这种缺失的上下文信息对理解被选中的控件,可能是至关重要的。

一个用户界面的示例,日历,还是日程计划的上下文是关键的。如果用户在周一到周五天列表选择了下午4点时间槽,无障碍服务发出“4 PM”的反馈,但是并没有发出星期的名字,这个月中的哪天,月份的名字,这个反馈的结果就是令人困惑的。在这个示例中,对于一个关心会议安排的用户,用户界面控件的上下文是至关重要的。

Android 4.0显著扩展了信息的数量,这些信息是无障碍服务通过基于视图层的无障碍事件获取的关于用户与界面交互的信息。一个视图层是一组用户界面组件,这些组件包含其父类的组件,及其子类组件的用户界面元素。一个视图层次结构是一组用户界面组件,包含组件(父母)和用户界面元素,可以包含由该组件(孩子们)。通过这种方式,Android系统能够提供更丰富的关于无障碍性事件的细节,允许无障碍服务提供更多有用的反馈给用户。

一个无障碍服务获取用户界面事件的信息,通过系统服务的[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#onAccessibilityEvent(android.view.accessibility.AccessibilityEvent)| onaccessibilityevent() ]]回调方法传递的[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityEvent.html | AccessibilityEvent ]]。这个对象提供关于事件的详细信息,包括对象的类型,其描述性文本和其他细节。从Android 4.0(和以前版本中通过在Support Library的[[ http://android-doc.com/reference/android/support/v4/view/accessibility/AccessibilityEventCompat.html| accessibilityeventcompat ]]支持),通过下面这些方法获取额外的关于事件的信息:

重点: 这种对试图层次的探查,可能通过[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityEvent.html | AccessibilityEvent ]]为你的无障碍服务,获得潜在用户私人信息。由于这个原因,您的服务必须通过无障碍服务配置XML文件,请求这种级别的访问,包括canRetrieveWindowContent属性设置为true。如果在您的[[ http://android-doc.com/guide/topics/ui/accessibility/services.html#service-config | service configuration XML ]]文件不包括此设置,调用[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityRecord.html#getSource() | getsource() ]]就会失败。

注意:在Android 4.1(API级别16)及以上,getSource()方法,以及AccessibilityNodeInfo.getChild()和getParent(),只返回视图对象,这被认为是(对绘制内容或者响应用户的操作的视图)重要的无障碍。如果你的服务要求所有视图,可以通过设置服务的AccessibilityServiceInfo实例的成员标志标记FLAG_INCLUDE_NOT_IMPORTANT_VIEWS来实现。

为用户做出动作


从Android 4.0(API级别14)开始,无障碍服务可以代表用户,包括改变输入焦点和选择(激活)的用户界面元素。在Android 4.1(API级别16)行动的范围已经被扩大到包括滚动列表和交互文本字段。无障碍服务也可以采取全局的行动,比如导航到主屏幕,按后退按钮,打开屏幕通知栏和最近的应用程序列表。Android 4.1还包括一个新类型的焦点,Accessibilty焦点,这使得无障碍服务可以选择所有可见的元素。

这些新功能可以让无障碍服务的开发人员去创建替代导航模式如手势导航,改进残疾人用户对他们的Android设备的控制成为可能。

监听手势

无障碍服务可以侦听特定的手势,对做出这个手势的用户给予响应。这个特性,添加在Android 4.1(API级别16),要求你的无障碍服务的请求通过触摸功能来激活的。你的服务可以请求通过设置服务的AccessibilityServiceInfo实例的成员标志为FLAG_REQUEST_TOUCH_EXPLORATION_MODE来激活,如下例所示。

public class MyAccessibilityService extends AccessibilityService {  
    @Override  
    public void onCreate() {  
        getServiceInfo().flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;  
    }  
    ...  
}  

一旦你的服务通过触摸激活,如果这个功能没有打开,用户必须打开功能。当这个功能被激活时,你的服务接收通知的无障碍手势通过你的服务的onGesture()回调方法,就可以对用户的行为做出响应。

使用无障碍行为

无障碍服务可以对用户的行为做出动作,使得与应用程序的交互更简单和更有效率。无障碍服务执行操作的能力添加于Android 4.0(API级别14),在Android 4.1(API级别16)明显的扩展了该能力。

为了做出的动作代表用户,你的无障碍服务必须注册去接收从几个或多个应用程序接收事件,必须通过在服务配置文件设置android:canRetrieveWindowContent为true,请求允许查看应用程序的内容。当你的服务接收到事件,它可以使用getSource()从事件检索AccessibilityNodeInfo对象。通过AccessibilityNodeInfo对象,您的服务可以探索视图层来决定采取何种行动,然后使用performAction()代理用户。

public class MyAccessibilityService extends AccessibilityService {  

    @Override  
    public void onAccessibilityEvent(AccessibilityEvent event) {  
        // get the source node of the event  
        AccessibilityNodeInfo nodeInfo = event.getSource();  

        // Use the event and node information to determine  
        // what action to take  

        // take action on behalf of the user  
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);  

        // recycle the nodeInfo object  
        nodeInfo.recycle();  
    }  
    ...  
}  

performAction()方法允许你的服务在一个应用程序中做出动作。如果你的服务需要执行全局性动作,如导航到主屏幕,按后退按钮,打开屏幕通知或最近的应用程序列表,使用performGlobalAction()方法。

使用焦点类型

这种类型的焦点可以通过无障碍服务选择任何可见的用户界面元素和作用于它。这个焦点类型不同于常见的输入焦点,当一个用户键入字符时,输入焦点决定了对屏幕上的界面元素输入,在键盘按Enter键或推动中心按钮的手柄控制的接收。
无障碍的焦点是完全的从输入焦点中独立出来。事实上,它可以让在一个用户界面的一个元素有输入焦点,而另一个元素有无障碍焦点。无障碍焦点的目的是提供无障碍服务,这个服务有与屏幕上任何可见元素进行交互的方法,无论从系统的视图元素的input-focusable是什么。你可以通过测试无障碍手势来看到在一个动作上的无障碍焦点。更多测试这个手势的信息,参考测试手势导航一节。

注意:使用无障碍焦点的无障碍服务,当一个元素可以希艾娜关于那个输入类型的焦点时,可以对输入类型焦点进行同步处理。没有同步处理输入焦点和无障碍焦点的服务,当多出某些动作时,在某个特定的位置,在应用程序中会有出现问题的风险。

一个无障碍服务可以使用AccessibilityNodeInfo.findFocus()方法决定哪些用户界面元素有输入焦点或无障碍焦点。你也可以使用focusSearch()方法,搜索带有输入焦点的,能被选中的元素。最后,你的无障碍服务可以使用performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS)方法设置无障碍焦点。

示例代码


API演示项目包含两个例子,这两个例子可以作为生成无障碍服务的开始 (/samples//ApiDemos/src/com/example/android/apis/accessibility):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值