2. 87.6%
Worldwide Android Market Share Q2 2016
(Share in Unit Shipments)
http://www.idc.com/prodserv/smartphone-os-market-share.jsp
3. It’s not easy to find Android apps
that are accessible.
4. Topics
1. Accessibility features and services of Android
2. General recommendations
3. Common problems
4. Accessibility API
5. Custom Views
6. Tools
5. How do people with
disabilities interact with
Android?
13. How can I improve the
accessibility of my Android
app?
14. Hearing
Audio/Video should provide optional captioning
Never convey meaningful information with sound alone
Make background sound / video easy to disable
15. Motor and Cognitive
Avoid complex gestures
Provide alternatives to custom gestures
Keep touch targets above 48x48 dp
Favor simple and hierarchical interfaces
Avoid screen clutter - favor navigation
Test your app with a Switch device, External Keyboard or D-Pad
16. Colors and Fonts
Always use scalable pixels for font sizes (‘sp’)
Never convey meaningful information with color alone
Texts should have a minimum color contrast ratio of 4.5 to 1
https://webaim.org/resources/contrastchecker/
Attention to what happens to your layout when fonts are increased
17. Avoid images with text
Label all meaningful images with content descriptions
Provide equal experiences
Vision
18. What are the most common
accessibility problems on
Android apps?
33. hint
android:hint
Creates a placeholder text within the input
Hint is not persistent when a value is added
It usually has color contrast problems
Still a valid method to add labels for TextInputLayout
40. Use android:importantForAccessibility and set it to no to make it irrelevant
for accessibility.
<ImageView
android:importantForAccessibility="no"
android:layout_width="wrap_content”
android:layout_height="wrap_content"
android:src="@drawable/background_image"/>
API 16+
Decorative views
48. Focus navigation
Use android:focusable or setFocusable(boolean) to control if a view should
receive focus.
Use requestFocus() to request the focus for the view.
API 1+
49. Focus navigation
Focus should follow natural reading order (Left to right, top to bottom).
Android will usually handle this for you. On rare occasions, you can modify it by
using:
android:nextFocusDown
android:nextFocusLeft
android:nextFocusRight
android:nextFocusUp
51. Focus Navigation
Focus on views that require user input.
(e.g. Buttons, Links, Check Boxes, Edit Texts, …)
Accessibility Focus
Focus for screen readers. Focus on all meaningful views
of the screen, including views that require no user input.
(e.g. non clickable text views)
52. Accessibility Traversal
Focus management modifies focus order but it does not modify the
accessibility focus order. If needed, use:
android:accessibilityTraversalAfter (Other view first)
android:accessibilityTraversalBefore (This view first)
API 22+
57. You can set an accessibility delegate to any view to provide more information
about the view for the accessibility service.
view.setAccessibilityDelegate(new AccessibilityDelegate() {
// a11y methods
// onInitializeAccessibilityEvent()
// onInitializeAccessibilityNodeInfo()
// ...
});
Accessibility Delegate
60. Aways best to use the default widgets
since they come accessible by default.
For this reason, avoid creating custom
views if not needed.
But if absolutely needed...
64. Accessibility Event
Event sent by the topmost view in the view tree to an accessibility service
when something notable happens in the user interface.
TYPE_VIEW_CLICKED
TYPE_VIEW_LONG_CLICKED
TYPE_VIEW_FOCUSED
TYPE_VIEW_TEXT_CHANGED
TYPE_VIEW_SCROLLED
65. Responsible for sending the event to accessibility services.
view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
sendAccessibilityEvent
66. Adds information about the accessibility event such as the state of the view.
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setChecked(true);
}
onInitializeAccessibilityEvent
67. Sets the spoken text prompt of the AccessibilityEvent for your view:
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(event);
event.getText().add(“This is what the a11y service will speak.”);
}
onPopulateAccessibilityEvent
68. announceForAccessibility
Convenience method for sending an AccessibilityEvent with
TYPE_ANNOUNCEMENT
For example, announcing a new notification.
public void showNotification() {
// ... some code to show notification on screen
announceForAccessibility("One new notification");
}
69. Accessibility Live Region
Convenience attribute that automatically notifies the user about changes to the
view’s content description or text (or children).
Example:
<TextView
android:id="@+id/error_message_box"
android:accessibilityLiveRegion="polite"
android:layout_width="wrap_content”
android:layout_height="wrap_content" />
70. Accessibility Live Region
None: Disable change notifications (Default for most views).
Polite: User should be notified for changes.
Assertive: Interrupts ongoing speech and notify the user immediately.
73. Accessibility Node Info
After obtaining an event, accessibility services can get a more detailed
information about the view that generated the event.
It’s a snapshot of a View state.
Provides info about:
Content
State
74. Accessibility Action
Defines actions that can be performed on a view:
Standard actions
Custom actions
Override standard actions
Actions can be reached via the Local Context Menu.
75. Accessibility Action
// register action
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
AccessibilityAction action = new AccessibilityAction(R.id.action_custom,
getString(R.string.action_custom));
info.addAction(action);
}
// implement what will happen once the action is triggered
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (action == R.id.action_custom) {
// do something
}
return true;
}
79. Explore By Touch Helper
Implement 5 methods which answers the following questions:
1. Which virtual view is selected when I touch on this X and Y coordinate?
2. Which virtual views are currently visible?
3. Add something to the Accessibility Event when an event happens to this
given virtual view? (Spoken Text)
4. Add something to the Accessibility Node Info when an accessibility service
requests for more info to this given virtual view? (Bounds, Spoken Text, State,
Actions)
5. What should happen if this given action is performed? (Click, Custom Actions)
An event has a type with additional information important for the event. For instance, TextView has to send and implement all possible events that could happen in the view, such as Selection Change, Focus Change, etc.
An event has a type with additional information important for the event. For instance, TextView has to send and implement all possible events that could happen in the view, such as Selection Change, Focus Change, etc.
An event has a type with additional information important for the event. For instance, TextView has to send and implement all possible events that could happen in the view, such as Selection Change, Focus Change, etc.
Android 4.0.x version and below: The default video player did not have support for subtitles. It needs to be implemented by the application.
Android 4.1 (Jelly Bean): The default video player has support for in-band and out-of-band text tracks. In-band text tracks come as a text track within an MP4 or 3GPP media source. Out-of-band text tracks can be added as an external text source via addTimedTextSource() method from MediaPlayer class. The subtitle is limited to SubRip format with the file extension .srt. More info on Android's versions page.
Mention to test on TalkBack during development
In the slide, we see 3 buttons that are not labeled. Each button is being described as “Unlabeled”.
We fix the problem by adding a meaningful content description to each image button.
Stop accessibility events from being sent. For older platforms, the only option is to not make it focusable.
In this slide, we see a list of multiple buttons with the same description: “Ignore” and “Connect”.
In this slide, we see a list of multiple buttons with the same description: “Ignore” and “Connect”.
In this slide, we see a list of multiple buttons with the same description: “Ignore” and “Connect”.
In this screen, we have a sort button with redundant description: “Button”.
In this screen, we have a sort button with redundant description: “Button”.
Stop accessibility events from being sent. For older platforms, the only option is to not make it focusable.
An event has a type with additional information important for the event. For instance, TextView has to send and implement all possible events that could happen in the view, such as Selection Change, Focus Change, etc.
In theory, you could also set the state in this method, but the recommended way is to do that in the onInitializeAccessibilityEvent() method.
Remember: Always best to use the default UI components
Remember: Always best to use the default UI components
Remember: Always best to use the default UI components
Example: When you focus on a Button, a11y services need to know what actions can be performed, what’s the current state of the button (Disabled?) etc.
Here we have code that shows how to add an action to a node info.
Tools help us reduce the amount of manual testing to be done. But don’t forget to manually test your app.