原理:view在获取焦点、点击、滑动等事件触发时,发出AccessiblityEvent事件,在AccessibilityService接收到相应事件后根据事件类型不同做出相应的处理。
1. Android内部控件
Android内置界面控件默认提供了无障碍支持。
读取顺序:焦点选中某一区域后,语音引擎会将区域内所有的控件从上向下、从左向右依次读出。gone的控件不会读取。
读取标签及优先级:contentDescription > text > hint,如果设置了contentDescription,则读contentDescription,如果没有设置contentDescription,则读取text,依次类推。如果TextView、Button、Checkbox这三种类型都没有设置,则读出“未设置标签”。
小区域:如果有比最小触摸尺寸还小的控件在应用屏幕中,考虑使用ViewGroup把他们分组,并为之提供android:contentDescription.
2. 自定义控件
如果自定义控件提供用户触摸交互的处理,例如onTouchEvent(MotionEvent)对MotionEvent.ACTION_DOWN和MotionEvent.ACTION_UP的监听,并将之视为一次点击事件。你必须触发一个AccessiblityEvent,等同于一次点击事件并为用户行为提供无障碍服务。
3. 增补无障碍音频反馈
Android内置控件对一些事件没有做出相应的无障碍支持,可以使用无障碍框架API动态增加来提供提示信息。例如自动翻页,使用announceForAccessibility(CharSequence)方法来让无障碍服务播放此信息的音频给用户。
4. 判断读屏状态
/**
* 读屏是否开启
*/
public static boolean isHasAccessibilityServiceEnable(Context context) {
int accessibilityEnable = 0;
try {
accessibilityEnable = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0);
} catch (Exception e) {
Log.e(TAG, "get accessibility enable failed, the err:" + e.getMessage());
}
if (accessibilityEnable != 1) {
return false;
}
String settingValue = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (TextUtils.isEmpty(settingValue)) {
return false;
}
return true;
}