Mystery Meat 2.0 – Making hidden mobile interactions accessible

Mystery Meat 2.0

  • Ted Drake, Intuit Accessibility
  • Poonam Tathavadkar, TurboTax
  • CSUN 2017
  • Slides: slideshare.net/7mary4

This presentation was created for the CSUN 2017 conference. It introduces several hidden interactions available within Android and iOS. Learn how these work and how to make them accessible.
Blue Bell Ice Cream Blue Bell Ice Cream web site with mystery meat navigationis a classic example still live on the web.

The user must hover over the different images to see what they represent. It uses an image map and lacks alt text.

Android Touch and Hold

A.K.A.: Android’s Right Click or Android Long Press to Add context-specific menus

  • Default: Touch and hold
  • With TalkBack:
    Double tap and hold to long press

Mint Transactions

This short video shows how you can use the touch and hold/long press to quickly change category or merchant name within the Mint application

Developers

  • onLongClick: Called when a view has been clicked
    and held
  • Define and Show your menu
  • Not for vital interactions.
  • This is a short
    cut.

It is possible to modify the default notification to the user

iOS 3D Touch

iOS 3D Touch was introduced on the iPhone 6S. It detects the pressure a person applies to the screen with their finger. I light touch is seen as a tap. A medium touch will
trigger a peek view. A continued firm touch will launch the peek’s content into a full screen.

This also allows a person to trigger a shortcut menu on app icons.

  • Peek:
    Quick glance at relevant information and
    actions
  • Pop:
    Open full content previewed in the Peek
  • Quick Actions:
    Custom task list from app icon

User Experience: A light press opens a hovering window so you can “Peek” at the content. When you press just a little bit harder, you will “Pop” into the actual content you’d just been
previewing in a Peek.

Developer info

Quick Actions

This short video shows how 3d touch is also available via the app’s icon for quick tasks.

Pressing and holding the ItsDeductible icon will trigger a menu with customized tasks. App Icon Developer resources

Developers

Swipe Revealed Actions

Alternative actions allow users to quickly make changes without having to open a detail screen. For instance, they can delete a transaction or change an email’s status. The standard interface is to display the options when a user swipes a row to the left. For voiceOver users, the options are announced as alternate actions

It’s Deductible Actions

This short video shows how the alternative actions menu is used in standard mode and how VoiceOver announces the options.

In iOS, editActionsForRowAtIndexPath defines the actions to display in response to swiping the specified row

  • Accessible by default
  • Define:
    • Target Action and Response
    • Visible Text
    • Background color

Swipe Based Navigation

TurboTax uses a custom swipe based navigation between views. It lacks button or suggestions to move back and forth. User testing has showed it to be effective for
sighted users, but required some extra work for accessibility.

Default Experience With VoiceOver

The default experience on Turbo Tax uses a custom swipe gesture that lacks navigation buttons.

TurboTax detects a user’s Screen Reader/Switch Control status to show navigation buttons on Android and iOS

This video shows the default and VoiceOver/SwitchControl experience.

Notice in the standard experience how the screen tracks the user’s finger movement. This is not a standard swipe gesture, so it will not work with VoiceOver enabled.

We detect VoiceOver and SwitchControl is running to display alternate back and continue buttons

Swipe Navigation

  • Animated transition between views
  • Next and Back flow with every screen
  • Eliminates navigation buttons
  • No buttons? Accessibility?
  • Have I reached the end of the screen?

Instead of a basic swipe gesture, this interface tracks the movement of the finger across the screen. This allows the animation to match the user’s finger speed for a more
natural transition.

However, the finger touch is intercepted by VoiceOver, so the custom navigation does not work when VoiceOver is enabled.

Detect Accessibility ON

UIAccessibility kit provides two methods

True == Show Navigation Buttons

These booleans always return true or false. We use this to insert navigation buttons into the screen.

State Change Notification

This does not solve for the more complex of when the user decides to turn it on/off in the middle of the flow of the application for changes to take place dynamically.

For that as well, iOS has great support. Fires an accessibilityChanged event that helps detect changes even when the user is in the middle of the flow and chooses to
turn voice over on/off.

User enables VoiceOver while on a screen

Detect the status change

TurboTax Helper Function

  • How can we refactor code to detect any
    accessibility related settings and address them
    together?
  • Helper function to the rescue!
  • NSNotificationCenter adds observers to track any
    settings that may require us to show buttons.
  • This is an OR logic. Example – if voice over OR
    switch control status changed, display buttons.

Code specifics

  • Boolean is assigned a value – true if buttons need to be shown.
  • Consider a React Native project, all this happens in the native code side (Objective C). This boolean is then handed over to the JAVASCRIPT side since it is not feasible
    for Javascript to get information directly from the device.

Android Accessibility – The Missing Manual

This presentation was created for the Bangalore Accessibility Week at Intuit, October 2015. It’s a collection of hard to discover information on making an Android application accessible.

Testing

DevicesTesting is done both on actual devices and with automation, such as Calabases and Android Lint. Intuit’s product development also relies heavily on user testing, including users with disabilities.

Intuit also has a mobile device library that allows anyone within Intuit to check out a mobile device for testing. This has significantly lowered equipment cost and makes it much easier to test applications on an assortment of phones. This can be important as phone manufacturers may break accessibility, such as the Samsung keyboard.

Android Lint

Android lint allows you to run accessibility tests within your development environment. It’s easy to find and fix the issues.

AccessibilityChecks

This session, Improve your Android App’s Accessibility, from Google IO 2015 introduces AccessibilityChecks and teases the upcoming testing app.

TalkBack

TalkBack is the built in screen reader for Android devices. ChromeVox is the screen reader used in Chrome and on ChromeOS

Turn on TalkBack

This video shows how to enable TalkBack and how to use it as a developer. It also shows how to use the context menu for reading the entire screen and turning of TalkBack temporarily.

Two Fingered Gestures

It is easy to use custom gestures with Android. If the app depends on a single finger gesture, TalkBack will pass the same gesture with two fingers. This is very helpful with signatures and swipe navigation.

Android Accessibility Shortcut

Android provides a convenient shortcut for enabling TalkBack on a device. This short video shows how to use it.

Programming

accessibilityLiveRegion

Place this declaration on the container that includes data that changes dynamically. The new content will be announced when it appears.

android:accessibilityliveregion="polite"

This short video shows how a live-region’s content is announced whenever it is changed by deselecting a row within the table. This is an HTML page with aria-live=“assertive”

AccessibilityAction

  • Swipes and other hard to discover actions
  • Actions are activated from the Local Context Menu
  • While this could be used to provide hints for actions, I haven’t found the documentation/examples on how this is accomplished.
Create AccessibilityAction
/**
 * @param actionId The id for this action. This should either be one of
 * the standard actions or a specific action for your app. In that case it
 * is required to use a resource identifier.
 */
 public AccessibilityAction(int id, CharSequence label)
 new AccessibilityAction(R.id.dismiss, getString(R.string.dismiss));
 new AccessibilityAction(ACTION_CLICK, getString(R.string.play_song));
// Constants for all the standard actions with default label:
 AccessibilityAction.ACTION_CLICK
Handling a Custom Action
eventView.setAccessibilityDelegate(new AccessibilityDelegate {
 @Override
 public onInitializeAccessibilityNodeInfo(
        View host, AccessibilityNodeInfo info) {
   super.onInitializeAccessibilityNodeInfo(host, info);
   info.addAction(new AccessibilityAction(R.id.dismiss,
 }
 @Override
   getString(R.string.dismiss)));
     public boolean performAccessibilityAction(
            View host, int action, Bundle args) {
      if (action == R.id.dismiss) {} // Logic for action
     }
 });

android:importantForAccessibility

diagram of UI layers within Android and setting noHideDescendants on unused layers. Use Auto on current layer

If you are using a stacked interface, where the hidden layers are still receiving focus, you can use importantForAccessibility to define the layers that are not important. Hamburger menus would be the most common use for this technique.

Set the visible layer to “auto”, which lets Android manage it’s functionality. Set the “hidden” layers to “noHideDesendants”, which should remove the layer and its children from the Accessibility API. Switch these values when you hide/show layers.

android:importantForAccessibility = "auto"
android:importantForAccessibility = "yes"
android:importantForAccessibility = "no"
android:importantForAccessibility = "noHideDescendants"

ListPopupWindow

diagram of a modal layer within Android. Use <a href=setModal(true) to make sure it acts like a modal view”>

For popups, such as a set of options A better option, however, may be to use a ListPopupWindow or PopupWindow if you’re attempting to display information in a modal context. Just be sure to setModal(true) to ensure the contents of that window, and only the contents of that window are focusable with TalkBack.

Forms

Forms are critical for a great user experience and we need to make sure our users understand what each input represents.

Form Labels

Which is correct for your app?

  • android:hint
  • android:labelFor
  • android:contentDescription

android:hint

The hint is like the HTML “placeholder” attribute. It is a visible label within the input and is surfaced to the Accessibility API when the input first receives focus. However, the hint is ignored when the input has a value. SSB Bart published a great article on this topic:
Android Accessibility Properties and TalkBack

Android form using android:hint, but no visual label

  • This create a placeholder text string within an input
  • This was the preferred method but is a hack
  • The hint is removed when a user adds a value to the input
  • Still a valid method of adding a label to an input

labelFor

The strongest method for adding a label to an input is the “labelFor” method. If your app has a visual text label, add “labelFor” to this text view and point it to the form input. The user will always know what the form input represents.
Android app using visual labels

<TextView
 android:layout_height="match_parent"
 android:labelFor="@+id/edit_item_name"
 android:text="Invoice amount"/>
<EditText
 android:id="@+id/edit_item_name"
 android:layout_height="wrap_content"
 android:hint="Invoice Amount"/>

contentDescription

ContentDescription is much like HTML’s “aria-label”. It’s an invisible text string that is surfaced directly to the Accessibility API. Android documentation specifically warns against using the contentDescription directly on the input.

Note: For EditText fields, provide an android:hint attribute instead of a content description, to help users understand what content is expected when the text field is empty. When the field is filled, TalkBack reads the entered content to the user, instead of the hint text.
Making Applications Accessible – Android Developer Portal

  • Invisible description for TalkBack
  • Should not be used directly on an input
  • You can use it on an input’s container and combine with labelFor

textinputlayout

It is possible to use “contentDescription” and “labelFor” to include a hidden label for your application. For instance, this pattern works with the recently introduced “textinputLayout” for Material Design layouts. This same pattern should work with a basic container around a form input.
Material design for form inputs include the android:hint as a visual label.

<textinputlayout
 android:labelfor="@id/signupemail"
 android:contentdescription="Email"
 android:accessibilityliveregion="polite">
  <edittext
   android:id="@id/signupemail"
   android:hint="Email"
   android:seterror="Create a valid email address"
    …/>
</textinputlayout> 

This is the pattern suggested for Material Design in Marshmallow. It has some bugs with Android support, but these should be solved soon. More information: Accessible Android Inputs with Material Design

Checking for TalkBack

AccessibilityManager am = (AccessibilityManager)
         getSystemService(ACCESSIBILITY_SERVICE);
boolean isAccessibilityEnabled = am.isEnabled();
boolean isExploreByTouchEnabled = am.isTouchExplorationEnabled();

You can check to see if the user has talkBack enabled and then make modifications to your application. For instance, this could be used to add continue and back buttons to a swipe-based navigation interface.

More Android Documentation

Accessible Android Inputs with Material Design

Update – August 2016

I first wrote this post shortly after textinputlayout was introduced and there was a distinct lack of documentation. My original code example for setting the error was incorrect. Per Victor Tsaran:

There is no such attribute as android:setError. There is a method called setError in the View class that can set the error message dynamically. That method actually works with TalkBack.
Victor Tsaran

I will be updating the code examples soon. For now, do not include the android:seterror line shown below. I’m leaving it right now for archival purposes.


Google has done an admirable job defining the Material Design style guide. They’ve also begun rolling out new APIs that make it much easier to implement the interaction designs within Android and HTML. However, there are still some gaps. This article looks at the popular Text Input for Android interaction. Please note: the code in this article is not fully documented and the best practice may change as the Google Accessibility team updates their documentation. Consider this a beta pattern and I will gladly update it as we learn better practices.
Continue Reading Accessible Android Inputs with Material Design

Android accessibility for developers and QA

Android Accessibility

Bangalore Accessibility Week October 6-10, 2014 Ted Drake, Intuit Accessibility

Continue Reading Android accessibility for developers and QA

Android Accessibility Testing and Fixing in 30 seconds

The Google Accessibility team recently invited Android developers from around the Bay Area to spend an afternoon learning how to make their applications accessible. The event showed these developers how easy it is to make their applications as accessible as possible. One of the tools featured was Android Lint. I was so impressed by the functionality that I made the following video: Android Accessibility Solution in 30 Seconds
Continue Reading Android Accessibility Testing and Fixing in 30 seconds