Making Applications Accessible
为Android构建的应用程序都与当这些用户激活设备上的无障碍服务和功能视力,肢体或与年龄相关的限制用户更容易获得。这些服务使应用程序更容易,即使你不做任何辅助功能更改你的代码。不过,也有你应该优化应用程序的可访问性,并确保为所有用户一个愉快的经历的步骤。
确保你的应用是所有用户都可以访问只需要几步,特别是当你创建了Android框架提供的组件的用户界面。如果你只使用标准组件为您的应用程序,步骤如下:
contentDescription属性:使用了android添加描述性文本用户界面控件在应用程序中。要特别注意的ImageButton,ImageView的和CheckBox。
确保可以接受输入(触摸或打字)所有用户界面元素可以用定向控制器达到,如轨迹球,D垫(物理或虚拟)或导航手势。
确保语音提示总是伴随着另一种视觉提示或通知,协助谁是失聪或有听力障碍的用户。
只用辅助导航服务和功能测试应用程序。打开话语提示和触摸浏览,然后再尝试使用你的应用程序只使用定向控制。有关测试的可访问性的更多信息,请参阅辅助功能测试清单。
如果你建立了扩展视图类自定义控件,你必须完成一些额外的工作,以确保您的组件都可以访问。本文讨论了如何自定义视图控件与无障碍服务兼容。
注:本文中的实施步骤描述制作与失明或低视力的用户您的应用程序访问的要求。一定要检讨谁是又聋又重听在辅助功能开发清单服务的用户的要求
。
标签用户界面元素
许多用户界面控件依赖于视觉提示来指示它们的含义和用法。例如,笔记应用程序可能使用的ImageButton带加号的照片,以表明用户可以添加一个新的注释。一个EditText组件可能接近它的标签,表明其目的。视力受损的用户看不到这些线索不够好,跟着他们,这让他们也没用。
您可以通过这些控件与Android更容易:contentDescription XML布局属性。在该属性的文本不会出现在屏幕上,但如果用户启用无障碍服务提供声音提示,那么当用户导航到该控件,文字转换成语音。
为此,设置了android:contentDescription属性为每一位的ImageButton,ImageView的,复选框在应用程序的用户界面,并添加描述那些可能需要谁不能够看到它的用户附加信息任何其他输入控件。
例如,下面的ImageButton设置的加号按钮向add_note字符串资源,这可以被定义为“添加记事”为英文界面内容说明
<ImageButton android:id=”@+id/add_note_button” android:src=”@drawable/add_note” android:contentDescription=”@string/add_note”/>通过包括描述,无障碍服务,提供语音反馈可以宣布“添加记事”当用户将焦点移动到该按钮或悬停。
android:nextFocusDown
android:nextFocusLeft
android:nextFocusRight
android:nextFocusUp
<LinearLayout android:orientation="horizontal" ... > <EditText android:id="@+id/edit" android:nextFocusDown=”@+id/text” ... /> <TextView android:id="@+id/text" android:focusable=”true” android:text="Hello, I am a focusable TextView" android:nextFocusUp=”@id/edit” ... /> </LinearLayout>当修改的焦点秩序,确保导航将按预期从每个用户界面控制所有的方向和反向航行时(要回你原来的地方)。
@Override public boolean onKeyUp (int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { mCurrentValue--; sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); return true; } ... }填充辅助活动
@Override public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { super.dispatchPopulateAccessibilityEvent(event); // Call the super implementation to populate its text to the event, which // calls onPopulateAccessibilityEvent() on API Level 14 and up. // In case this is running on a API revision earlier that 14, check // the text content of the event and add an appropriate text // description for this custom view: CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { event.getText().add(text); } }为Android 4.0(API等级14)和更高,使用onPopulateAccessibilityEvent()和onInitializeAccessibilityEvent()方法来填充或修改一个AccessibilityEvent的信息。使用onPopulateAccessibilityEvent()方法专门为添加或修改的情况下,这是由无障碍服务变成声音提示,如话语提示的文本内容。使用用于填充有关事件,其他信息onInitialize AccessibilityEvent()方法,如视图的选择状态。
ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() { @Override public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) { super.onPopulateAccessibilityEvent(host, event); // We call the super implementation to populate its text for the // event. Then we add our text not present in a super class. // Very often you only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { event.getText().add(text); } } @Override public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { super.onInitializeAccessibilityEvent(host, event); // We call the super implementation to let super classes // set appropriate event properties. Then we add the new property // (checked) which is not supported by a super class. event.setChecked(isChecked()); } @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) { super.onInitializeAccessibilityNodeInfo(host, info); // We call the super implementation to let super classes set // appropriate info properties. Then we add our properties // (checkable and checked) which are not supported by a super class. info.setCheckable(true); info.setChecked(isChecked()); // Quite often you only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { info.setText(text); } } }在针对应用的Android 4.0(API等级14)和更高版本,可以在自定义视图类直接实现这些方法。对于这种方法的另一个例子,看到了Android支持库(修订5或更高)样品AccessibilityDelegate SupportActivity中(<SDK> /演员/安卓/支持/ V4 /样本/ Support4Demos /)。
图1.选择一天元素自定义日历视图。
在图1所示的例子中,整个日历实现为单个视图中,因此,如果不这样做别的,无障碍服务不会收到关于视图的视图中的内容和用户的选择的足够信息。例如,如果用户点击包含17天,可访问性框架只接收整个日历控件的描述信息。在这种情况下,话语提示辅助服务将简单地宣布“日历”,或者只是稍微好一点,“四月日历”,用户将留待知道选择什么日子。
在这样的情况下提供足够的上下文信息无障碍服务,该框架提供了一种方法来指定一个虚拟视图层次。虚拟视图层次是应用程序开发者提供了互补的视图层次到屏幕上的实际信息更加匹配的无障碍服务的一种方式。这种方法允许无障碍服务提供更多有用的上下文信息给用户。
其中,可能需要的虚拟视图层次的另一种情况是含有一组控件(次)一个用户界面,密切相关的功能,其中,在一个控制动作会影响一个或多个元素,的内容例如与单独一个数字选择器向上和向下的按钮。在这种情况下,因为在一个控制作用改变在另一内容和这些控制的关系可以不向服务是显而易见无障碍服务不能获得足够的信息。为了处理这种情况,组相关的控件与含有视图,并提供从这个容器的虚拟视图层次明确表示由控件提供的信息和行为。
为了给视图提供一个虚拟视图层次,在自定义视图或视图组覆盖getAccessibilityNodeProvider()方法,并返回AccessibilityNodeProvider的实现。举一个例子执行这一辅助功能,请参阅AccessibilityNodeProviderActivity在ApiDemos示例项目。您可以实现与Android 1.6及更高版本通过使用支持库与ViewCompat.getAccessibilityNodeProvider()方法,并提供与AccessibilityNodeProviderCompat实现兼容的虚拟视图层次。
处理自定义触摸事件
自定义视图控件可能需要非标准的触摸事件的行为。例如,一个自定义的控制可以使用onTouchEvent(MotionEvent)监听法检测ACTION_DOWN和ACTION_UP事件,并触发特殊click事件。为了保持与无障碍服务,处理这一定义点击事件必须执行以下代码兼容性:
生成的解释点击动作适当AccessibilityEvent。
启用无障碍服务执行对于谁是不能够使用触摸屏的用户自定义点击动作。
要处理的有效途径这些要求,你的代码应该重写performClick()方法,它必须调用超级此方法的实现,然后执行由点击事件所需的任何行动。当检测到自定义的点击动作,该代码应该再打电话给你performClick()方法。下面的代码示例演示了这种模式。
class CustomTouchView extends View { public CustomTouchView(Context context) { super(context); } boolean mDownTouch = false; @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); // Listening for the down and up touch events switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDownTouch = true; return true; case MotionEvent.ACTION_UP: if (mDownTouch) { mDownTouch = false; performClick(); // Call this method to handle the response, and // thereby enable accessibility services to // perform this action for a user who cannot // click the touchscreen. return true; } } return false; // Return false for other touch events } @Override public boolean performClick() { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any super.performClick(); // Handle the action for the custom click here return true; } }上面显示的模式可确保定制的单击事件使用performClick()方法都产生一个辅助活动,提供一个切入点无障碍服务代表用户的行为来执行这个自定义click事件与无障碍服务兼容。