Accessibility辅助功能的使用

前言

又到春节,大家这几天抢红包抢得高兴吗?最近,安卓“辅助功能”特性的应用倒是越来越火了,比如免Root自动安装应用、微信自动抢红包等,这些都是利用安卓的Accessibility实现的,所以是时候了解一下Accessibility了。

介绍

官方介绍:
许多Android用户有不同的能力,要求它们以不同的方式与他们的Android设备进行交互。这包括用户视觉、物理或年龄限制,防止他们完全看到或使用触摸屏,和用户与听力损失可能无法感知声音和警报信息。
Android提供了可访问性特性和服务更容易帮助这些用户导航设备,包括语音、触觉反馈,手势导航,轨迹球和directional-pad导航。Android应用程序开发人员可以利用这些服务使应用程序更容易。
Android开发者也可以建立自己的可访问性服务,可以提供增强的可用性特性,比如音频提示物理反馈,和替代导航模式。可访问性服务可以为所有应用程序提供这些增强功能,一组应用程序或只是一个单一的应用程序。

辅助功能

一个可访问性服务是一个应用程序,该应用程序提供用户界面增强帮助残障人士,或可能暂时无法完全与设备进行交互。例如,用户驾驶,照顾一个小孩或者参加一个非常热闹的派对可能需要额外的或替代接口反馈。
Android提供了标准的易访问性服务,包括反馈,开发人员可以创建和分发自己的服务。本文解释了构建一个可访问性的基础服务。

申明清单和权限

提供可访问性服务的应用程序必须包括具体声明他们的应用程序表现被视为一个可访问性服务的Android系统。

第一步: Manifest可访问性服务声明

  • 声明服务

    1
    2
    3
    4
    5
    6
    7
    <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>
    </service>
  • 声明权限

    1
    <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />

第二步: 可访问性服务配置

在目录<project_dir>/res/xml/accessibility_service_config.xml创建xml资源文件:

1
2
3
4
5
6
7
8
9
10
<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"
/>

Manifest中引用:

1
2
3
4
5
6
<service android:name=".MyAccessibilityService">
...
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />

</service>

关于各个属性详解参见谷歌官方的AccessibilityServiceInfo文档

第三步: 注册为可访问性事件

可访问性的最重要的一个功能服务配置参数允许您指定您的服务可以处理什么类型的可访问性的事件。能够指定该信息相互配合支持可访问性服务,并允许你只作为开发人员灵活地处理特定事件类型从特定应用程序。事件过滤可以包括下列标准:

  • 包名 - 指定包名的应用程序的可访问性你想要你的服务来处理事件。如果省略该参数,那么你的可访问性服务被认为是用于服务为任何应用程序可访问性活动。在Service中配置 android:packageNames属性即可。
  • 事件类型 - 指定类型的可访问性你想要你的服务来处理事件。使用 android:accessibilityEventTypes属性,如 accessibilityEventTypes="typeViewClicked|typeViewFocused"

当设置可访问性服务时,仔细考虑你服务是能够处理事件,只有注册这些事件。因为用户可以激活一个以上的可访问性服务,你的服务不能使用它无法处理的事件。记住,其他服务可能会处理这些事件以改善用户的体验。

第四步: 重写方法

继承 AccessibilityService类,重写服务开始时( onServiceConnected())、运行时( onAccessibilityEvent(), onInterrupt())、关闭( onUnbind())四个方法。

四个方法的具体调用细节参见AccessibilityService实现

第五步: 获取事件详情

无障碍服务通过获取有关用户接口事件信息 AccessibilityEvent由系统传递到服务的 onAccessibilityEvent()回调方法。

  • AccessibilityEvent.getRecordCount()和getRecord(int) - 这些方法允许您检索一套AccessibilityRecord这有助于对象AccessibilityEvent传递给你的系统。这种详细程度为触发您的无障碍服务事件的详细内容。
  • AccessibilityEvent.getSource() - 这个方法返回一个AccessibilityNodeInfo对象。这个对象允许您请求视图布局层次(父母和子女)发起的辅助事件的组件。此功能允许无障碍服务,调查事件的完整的上下文,包括任何封闭视图或子视图的内容和状态。

第六步: 使用可访问性动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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();
}
...
}

结语

至此,此文结束,只是写了一些来自官方文档的理论知识,这是利用这一特性进行实践的基础,所以相当地需要好好消化。

PS: 最近发现一字一句手打博客效率实在是太低了,所以在以后的博客中我会多使用翻译软件和复制粘贴等来提高效率,这样也许就会造成有部分字词用词不当等问题(如果有什么大的问题可以联系我,我会及时修改),还请谅解。