29
Enabling Blind and Low-Vision Accessibility Designing custom widgets to fully support platform APIs Casey Burkhardt - Software Engineer, Google T.V Raman - Research Scientist, Google Alan Viverette - Software Engineer, Google

Enabling Blind and Low-Vision Accessibility on Android

Embed Size (px)

DESCRIPTION

Enabling Blind and Low-Vision Accessibility on Android

Citation preview

Page 1: Enabling Blind and Low-Vision Accessibility on Android

Enabling Blind andLow-Vision AccessibilityDesigning custom widgets to fully support platform APIs

Casey Burkhardt - Software Engineer, GoogleT.V Raman - Research Scientist, GoogleAlan Viverette - Software Engineer, Google

Page 2: Enabling Blind and Low-Vision Accessibility on Android

Introduction

Watch previous talks for history and deep dives on core concepts in Androidaccessibility

Android makes it simple to deploy an application across a large number ofdevices

Making your Android applications accessible will help reach the widestaudience possible

·

·

·

3/31

Page 3: Enabling Blind and Low-Vision Accessibility on Android

Accessibility services

TalkBack (Froyo and above)

BrailleBack (Jelly Bean and above)

·

Provides spoken, auditory, and haptic feedback to blind and low-visionusers

Allows for random access and linear access of content

-

-

·

Allows users to access content on a refreshable braille display

Supports navigation and text input from a braille keyboard

-

-

4/31

Page 4: Enabling Blind and Low-Vision Accessibility on Android

Accessibility focus

Like input focus, but can be placed on any view

Indicated visually with a yellow rectangle

Assigned by TalkBack based on user interaction

Indicates the active target for actions

Location determined according to heuristics

·

·

·

·

·

Most fine-grained actionable view

View with textual content if there is no actionablecontainer

-

-

5/31

Page 5: Enabling Blind and Low-Vision Accessibility on Android

Accessibility focus example

6/31

Page 6: Enabling Blind and Low-Vision Accessibility on Android

Demo: Interacting with accessibility services

TalkBack

BrailleBack

·

Touching an item moves accessibility focus

Swipe gestures move accessibility focus linearly

Double-tap activates the focused item

Various other directional gestures for common functions

-

-

-

-

·

Accessibility focus moved using the keys on a refreshable braille display

Click actions sent through key presses on the display

Includes virtual braille overlay

-

-

-

7/31

Page 7: Enabling Blind and Low-Vision Accessibility on Android

Basic application accessibility

Standard framework widgets are accessible

Label non-text views with content descriptions

Follow W3C WAI guidelines for any web content

Custom widgets almost always need extra work

·

·

Populate android:contentDescription for all non-text views

Set android:contentDescription="@null" for decorative views

Call View.setContentDescription if a view's meaning changesdynamically

For controls (e.g. Switch), set android:labelFor to provide extra context

-

-

-

-

·

·

8/31

Page 8: Enabling Blind and Low-Vision Accessibility on Android

Example of a custom BarGraphView

Widget features

Implementation details

From an accessibility service, this view looks completely empty

·

Renders an int[] as a bar graph

Clicking on a bar highlights it

-

-

·

Extends View

Adds methods for setData() and setTitle()

Overrides onDraw() to render title, bars, and axes

Overrides onTouchEvent() to detect clicking on bars

-

-

-

-

·

9/31

Page 9: Enabling Blind and Low-Vision Accessibility on Android

Advanced accessibilityusing ExploreByTouchHelperAn easy way to implement accessibility in custom views

Page 10: Enabling Blind and Low-Vision Accessibility on Android

What's in a View?

Dimensions and positioning

Graphics and/or text

User interaction model

Other views?

·

·

·

·

11/31

Page 11: Enabling Blind and Low-Vision Accessibility on Android

What's in an AccessibilityNodeInfo?

Dimensions and positioning

Description and/or text

User interaction model

Child nodes

·

·

·

·

12/31

Page 12: Enabling Blind and Low-Vision Accessibility on Android

Introducing the ExploreByTouchHelper

Simplifies exposing a virtual view hierarchy

Wraps AccessibilityNodeProviderCompat

Works with screen readers, Braille, and more

Backwards compatible with API 4

·

Just five simple abstract methods-

·

·

·

13/31

Page 13: Enabling Blind and Low-Vision Accessibility on Android

Implementing an ExploreByTouchHelper

Delegate handling of certain events

Implement support for Explore by Touch

Expose information to accessibility services

Provide support for user interaction

Test, ensure feature parity

·

·

·

·

·

14/31

Page 14: Enabling Blind and Low-Vision Accessibility on Android

Delegating accessibility support

private final BarGraphTouchHelper mBarGraphTouchHelper;

public BarGraphView(Context context, AttributeSet attrs, int defStyle) { ...

mBarGraphTouchHelper = new BarGraphTouchHelper(this); ViewCompat.setAccessibilityDelegate(this, mBarGraphTouchHelper);}

@Overridepublic boolean dispatchHoverEvent(MotionEvent event) { // Dispatch hover events to accessibility first. if (mBarGraphTouchHelper.dispatchHoverEvent(event)) { return true; } return super.dispatchHoverEvent(event);}

JAVA

15/31

Page 15: Enabling Blind and Low-Vision Accessibility on Android

Implementing an ExploreByTouchHelper

Delegate handling of certain events

Implement support for Explore by Touch

Expose information to accessibility services

Provide support for user interaction

Test, ensure feature parity

·

·

·

·

·

16/31

Page 16: Enabling Blind and Low-Vision Accessibility on Android

Mapping logical items to virtual view ids

Logical items are referenced by the framework as virtual view ids

Developer must guarantee virtual view ids are

BarGraphView can reuse data array indices

·

·

One-to-one

Stable

Non-negative

-

-

-

·

Virtual view id 0 maps to bar for data index 0-

17/31

Page 17: Enabling Blind and Low-Vision Accessibility on Android

Exposing on-screen placement of items

@Overrideprotected int getVirtualViewIdAt(float x, float y) { // We already map (x,y) to bar index for hit detection for onTouchEvent(). int index = getBarIndexAt(x, y); if (index >= 0) { return index; } return ExploreByTouchHelper.INVALID_ID;}

@Overrideprotected void getVisibleVirtualViewIds(List<Integer> virtualViewIds) { int count = getBarCount(); for (int index = 0; index < count; index++) { virtualViewIds.add(index); }}

JAVA

18/31

Page 18: Enabling Blind and Low-Vision Accessibility on Android

Implementing an ExploreByTouchHelper

Delegate handling of certain events

Implement support for Explore by Touch

Expose information to accessibility services

Provide support for user interaction

Test, ensure feature parity

·

·

·

·

·

19/31

Page 19: Enabling Blind and Low-Vision Accessibility on Android

Exposing item properties

<string name="bar_desc">Bar %1$d, value %2$d</string><string name="bar_desc_highlight">Bar %1$d, value %2$d highlighted</string>

XML

// Speaks the index and value. Informative, but not verbose.private CharSequence getDescriptionForIndex(int index) { int value = getBarValue(index); int templateRes = ((mHighlightIndex == index) ? R.string.bar_desc_highlight : R.string.bar_desc); return getContext().getString(templateRes, index, value);}

@Overrideprotected void populateEventForVirtualViewId(int virtualViewId, AccessibilityEvent evt) { CharSequence desc = getDescriptionForIndex(virtualViewId); evt.setContentDescription(desc);}

JAVA

20/31

Page 20: Enabling Blind and Low-Vision Accessibility on Android

Exposing item properties

@Overrideprotected void populateNodeForVirtualViewId( int virtualViewId, AccessibilityNodeInfoCompat node) { // Node and event descriptions are usually identical. CharSequence desc = getDescriptionForIndex(virtualViewId); node.setContentDescription(desc);

// Since the user can tap a bar, add the CLICK action. node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);

// Reported bounds should be consistent with onDraw(). Rect bounds = getBoundsForIndex(virtualViewId); node.setBoundsInParent(bounds);}

JAVA

21/31

Page 21: Enabling Blind and Low-Vision Accessibility on Android

Implementing an ExploreByTouchHelper

Delegate handling of certain events

Implement support for Explore by Touch

Expose information to accessibility services

Provide support for user interaction

Test, ensure feature parity

·

·

·

·

·

22/31

Page 22: Enabling Blind and Low-Vision Accessibility on Android

Responding to actions

@Overrideprotected boolean performActionForVirtualViewId( int virtualViewId, int action, Bundle arguments) { switch (action) { case AccessibilityNodeInfoCompat.ACTION_CLICK: // Click handling should be consistent with onTouchEvent(). onBarClicked(virtualViewId); return true; }

// Only need to handle actions added in populateNode. return false;}

JAVA

23/31

Page 23: Enabling Blind and Low-Vision Accessibility on Android

Sending appropriate events

public class BarGraphView extends View { ...

public void onBarClicked(int index) { ...

// Highlighting affects the bar description. mBarGraphTouchHelper.invalidateVirtualViewId(index);

// Send a CLICKED event to ensure consistent feedback. mBarGraphTouchHelper.sendEventForVirtualViewId(index, AccessibilityEvent.TYPE_VIEW_CLICKED); }}

JAVA

24/31

Page 24: Enabling Blind and Low-Vision Accessibility on Android

Implementing an ExploreByTouchHelper

Delegate handling of certain events

Implement support for Explore by Touch

Expose information to accessibility services

Provide support for user interaction

Test, ensure feature parity

·

·

·

·

·

25/31

Page 25: Enabling Blind and Low-Vision Accessibility on Android

Polishing the user experience

<string name="bar_graph_desc">%1$s bar graph, showing %2$d bars</string> XML

public class BarGraphView extends View { ...

public void setTitle(CharSequence title) { ...

// Speaks the title and number of bars shown. int count = getBarCount(); setContentDescription(getContext().getString( R.string.bar_graph_desc, title, count)); }}

JAVA

26/31

Page 26: Enabling Blind and Low-Vision Accessibility on Android

Implementing an ExploreByTouchHelper

Delegate handling of certain events

Implement support for Explore by Touch

Expose information to accessibility services

Provide support for user interaction

Test, ensure feature parity

·

·

·

·

·

27/31

Page 27: Enabling Blind and Low-Vision Accessibility on Android

Summary of ExploreByTouchHelper

Accessibility in custom views is easy·

28/31

Page 28: Enabling Blind and Low-Vision Accessibility on Android

Conclusion

Writing accessible Android applications is easy

Android has built-in accessibility support

Good accessibility can increase your user base and make users happy

·

·

·

29/31

Page 29: Enabling Blind and Low-Vision Accessibility on Android

Thank You!Source code available at eyes-free.googlecode.com

For demos and more information, please stop bythe Accessibility sandbox on the second floor.

Casey Burkhardt - Software Engineer, GoogleT.V Raman - Research Scientist, GoogleAlan Viverette - Software Engineer, Google