Android无障碍开发

创建无障碍服务

  创建MyAccessibilityService类并继承AccessibilityService类,重写其中的onAccessibilityEvent方法和onInterrupt方法

1
2
3
4
5
6
7
8
9
10
11
public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

}

@Override
public void onInterrupt() {

}
}

清单声明和权限

  在清单文件中注册无障碍服务MyAccessibilityService,使用BIND_ACCESSIBILITY_SERVICE保护无障碍服务,确保只有系统有权限绑定服务,禁止第三方软件绑定

  label属性定义服务在系统中显示的名称

1
2
3
4
5
<service android:name=".service.MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="@string/accessibility_service_label"
android:exported="false">
</service>

  添加无障碍服务过滤器

  添加一个<meta-data>元素,用于定义无障碍服务的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
<service android:name=".service.MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="@string/accessibility_service_label"
android:exported="false">

<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>

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

  无障碍服务定义在xml文件accessibility_service_config

  其中属性的作用如下

  • description: 无障碍服务启用页面的详细描述
  • packageNames: 填入需要支持无障碍服务的包名,可以定义多个,以逗号分隔,留空代表支持所有应用
  • accessibilityEventTypes: 服务要接收的事件类型,在AccessibilityService中响应,只有声明之后系统才会调用服务类的onAccessibilityEvent
    • typeViewClicked: 点击事件
    • typeViewSelected: View被选择
    • typeViewScrolled: 滑动事件
    • typeWindowContentChanged: 窗口内容改变
    • typeAllMask: 所有事件
  • accessibilityFlags: 额外声明
  • accessibilityFeedbackType: 反馈类型
    • feedbackSpoken 语音反馈
    • feedbackHaptic 触觉(震动)反馈
    • feedbackAudible 音频反馈
    • feedbackVisual 视频反馈
    • feedbackGeneric 通用反馈
    • feedbackAllMask 以上所有
  • notificationTimeout: 同一种事件类型触发的最短时间间隔
  • canRetrieveWindowContent: 是否允许获取屏幕信息
  • canPerformGestures: 是否允许手势,自定义xy坐标点击或者自定义手势必须打开
  • settingsActivity: 允许修改此服务设置的activity
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="feedbackAllMask"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
android:canPerformGestures="true"
android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"/>

无障碍服务方法

onServiceConnected

  当系统成功连接到无障碍服务时,会调用此方法。

onAccessibilityEvent

  当系统检测到与无障碍服务指定的事件过滤参数匹配的AccessibilityEvent时,会回调此方法

onInterrupt

  当系统要中断服务正在提供的反馈(通常是为了响应将焦点移到其他控件等用户操作)时,会调用此方法

onUnbind

  当系统将要关闭无障碍服务时,会调用此方法

自动点击

点击指定x、y坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void simulateClick(float x, float y) {
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
Path clickPath = new Path();
clickPath.moveTo(x, y);
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(clickPath, 0, 100));
GestureDescription gesture = gestureBuilder.build();
dispatchGesture(gesture, new GestureResultCallback() {
@Override
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
// 点击完成后的回调
}

@Override
public void onCancelled(GestureDescription gestureDescription) {
super.onCancelled(gestureDescription);
// 点击取消后的回调
}
}, mHandler);
}

自定义手势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void simulateGesture(float fromX, float fromY, float toX, float toY) {
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
Path gesturePath = new Path();
gesturePath.moveTo(fromX, fromY); // 启点
gesturePath.lineTo(toX, toY); // 终点
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(gesturePath, 0, 100));
GestureDescription gesture = gestureBuilder.build();
dispatchGesture(gesture, new GestureResultCallback() {
@Override
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
// 手势完成后的回调
}

@Override
public void onCancelled(GestureDescription gestureDescription) {
super.onCancelled(gestureDescription);
// 手势取消后的回调
}
}, mHandler);
}