构建无障碍服务

[[ 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中包含一个元素引用一个配置文件,它允许您为您的无障碍服务设置整个范围的选项,如下例所示:

".MyAccessibilityService">  ...  "android.accessibilityservice"    android:resource="@xml/accessibility_service_config" />

这个 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属性的信息,请按照以下链接到参考文档:

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_description| android:description ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_packageNames| android:packageNames ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_accessibilityEventTypes| android:accessibilityEventTypes ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_accessibilityFlags| android:accessibilityFlags ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_accessibilityFeedbackType| android:accessibilityFeedbackType ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_notificationTimeout| android:notificationTimeout ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_canRetrieveWindowContent | android:canRetrieveWindowContent ]]

  • [[ http://android-doc.com/reference/android/R.styleable.html#AccessibilityService_settingsActivity| android:settingsActivity ]]

    更多可以在运行时动态地设置配置的信息,请参阅,参见[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityServiceInfo.html| AccessibilityServiceInfo ]]参考文档。

注册无障碍事件

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

  • 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() ]])。

  • [[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#onServiceConnected() | onserviceconnected() ]] -(可选)当应用成功连接到你的无障碍服务时,系统调用该方法。使用这个方法为你的无障碍服务做任何一次性设置的步骤,包括连接到用户反馈的系统服务,如音频管理器或设备振动器。如果你想在运行时或者一次性调整你服务的配置,这是一个方便的位置,这种情况时调用[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo) | setServiceInfo() ]]。

  • [[ 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 ]]相时,调用该方法。例如,当用户在一个应用程序中点击一个按钮或焦点放在用户界面控件上时,,你的无障碍服务就可以提供反馈。这种情况下,系统就通过相关连的[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityEvent.html| AccessibilityEvent ]],调用这个方法,然后服务就可以解释和使用为用户提供的反馈了。这个方法在服务的生命周期中可能会被多次调用。

  • [[ 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系统以[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityEvent.htm | AccessibilityEvent ]]对象的形式对用户提供的返回的数据,如何处理它们由你来决定。更多关于获取信息的无障碍事件的信息,参考实现无障碍训练章节。

获取事件的注意事项

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#getRecordCount()| AccessibilityEvent.getRecordCount() ]]和[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityEvent.html#getRecord(int)| getRecord(int) ]]——这些方法允许你检索[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityRecord.html | AccessibilityRecord]]对象集合,这也使得你通过系统获得[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityEvent.html | AccibilityEvent ]]。这种层次的细节为这个触发你无障碍服务的事件提供了更多的上下文。

  • [[ http://android-doc.com/reference/android/view/accessibility/AccessibilityRecord.html#getSource() | AccessibilityEvent.getSource() ]] - 这个方法返回一个[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityNodeInfo.html| AccessibilityNodeInfo]]对象。该对象允许您请求(父母和孩子)的组件的视图布局层,源于无障碍事件。这个特性允许一个无障碍服务调查事件的整个上下文,包括内容和任何封闭视图或子视图的状态。

重点: 这种对试图层次的探查,可能通过[[ 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):

  • [[ http://android-doc.com/resources/samples/ApiDemos/src/com/example/android/apis/accessibility/ClockBackService.html| ClockBackService]] - 这项服务是基于最初[[ http://android-doc.com/reference/android/accessibilityservice/AccessibilityService.html| accessibilityservice ]]的实现,可以作为开发基本的无障碍服务的基础,这些服务都是兼容Android1.6(API级别4)以上版本。

  • [[ http://android-doc.com/resources/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.html| TaskBackService ]] - 这个服务是基于在Android 4.0(API级别14)中引入的增强了的无障碍API。然而,你可以使用Android [[ http://android-doc.com/tools/extras/support-library.html| Support Libary ]] 替代替之后API中引入的类 (例如,[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityRecord.html| AccessibilityRecord ]],[[ http://android-doc.com/reference/android/view/accessibility/AccessibilityNodeInfo.html| AccessibilityNodeInfo ]])与等效支持包类 (例如 [[ http://android-doc.com/reference/android/support/v4/view/accessibility/AccessibilityRecordCompat.html| AccessibilityRecordCompat ]],[[ http://android-doc.com/reference/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.html | AccessibilityNodeInfoCompat ]]),使得这个例子可以使用在Android 1.6(API 4)的版本上。

更多相关文章

  1. Android(安卓)Touch事件传递机制解析
  2. 让editView、AutoCompleteTextView开始捕获的焦点
  3. Android(安卓)Service总结03 之被启动的服务 -- Started Service
  4. 《Android和PHP最佳实践》官方站
  5. Android(安卓)EventBus使用,粘性事件postSticky使用
  6. Android(安卓)Service总结04 之被绑定的服务 -- Bound Service
  7. Android菜鸟的成长笔记(11)——Android中的事件处理
  8. Android(安卓)Service总结02 service介绍
  9. Android日志打印与处理 UncaughtExceptionHandler 提交服务器

随机推荐

  1. Android系统自带样式(android:theme)详解
  2. android 资源引用
  3. android ImageView的属性android:scaleTy
  4. android在Gridview实现Textview跑马灯效
  5. android知识点记录
  6. Android实现LIstView条目单选和多选Radio
  7. Android(安卓)GridLayout 的 columnSpan
  8. android button 透明背景色
  9. android 文本走马灯代码
  10. Android(安卓)使用 TableLayout 布局拉伸