Custom Accessibility Services

In the first post, I talked about making apps accessible to all. In this second and final post I will explain how to create an accessibility service and what can be the intentions behind creating one.

How to create a custom accessibility service?

  • Create a class that extends AccessibilityService and override onAccessibilityEvent(AccessibilityEvent event) and onInterrupt() methods.
    • onAccessibilityEvent() - This method is called back by the system when it detects an AccessibilityEvent that matches the event filtering parameters specified by our accessibility service.
    • onInterrupt() - This method is called when the system wants to interrupt the feedback our service is providing, usually in response to a user action such as moving focus to a different control.

  • Make an entry of the above defined service in AndroidManifest file. Here, The action and permission are required by the system to identify it as an AccessibilityService.
  • CustomAccessibilityService should have a configuration file which specifies the package names from which this service would like to receive events, the types of AccessibilityEvent that the service handles and information like whether the service can retrieve window content or not. Following are the descriptions of main entries of configuration file:
    • android:settingsActivity - This is used to specify a settings activity for this service(if any).
    • android:packageNames - This is used to specify package names of the apps this service should receive events from. If one would like their service to receive events from all apps then one can leave out this option.
    • android:accessibilityEventTypes - This is used to specify the event types this service would listen to like typeViewClicked, typeViewLongClicked. For listening to all event types typeAllMask is used.
    • android:accessibilityFeedbackType - The feedback types this service provides are specified
 using this attribute. Feedback types are like feedbackHaptic, feedbackSpoken.
    • android:notificationTimeout - This is used to specify the minimal period in milliseconds between two accessibility events of the same type are sent to this service.

    Other attributes are listed here. Add meta-data tag in Manifest declaration like this:

    Add the following file in res/xml directory


    For doing this programmatically, one has to override onServiceConnected method and use AccessibilityServiceInfo class to set the above mentioned parameters. However, not all configuration options are available using this method.

  • Finally when the events defined in service configuration occur, the system fires Accessibility events which are caught by onAccessibilityEvent method overridden in CustomAccessibilityService where one can specify what action should be taken on respective events.
    Below is a gist code where the service will speak out text from all text nodes present in the current window by using TextToSpeech engine on AccessibilityEvent typeWindowContentChanged. The demo application for this example can be found here.

Why custom accessibility service?

AccessibilityServices have been there in Android since Donut(API LEVEL 4) and its intention was to make OS and apps accessible for disabled people. But now organizations are using it for many other purposes. For example there are a few price comparison apps which use data from CustomAccessibilityService to figure out the product currently viewed by the user and provide alternative sites/apps for best prices of the respective product.
With the help of AccessibilityService we can retrieve window content of the device which is not available by other means, this opens a new horizon for application developers and the possibilities of utilizing this content are endless.

Explore it further and leave a comment for us about your use case of AccessibilityService.


Accessibility: Increasing app reachability

I always thought of accessibility services in Android meant to help people with visual or physical disabilities in accessing apps, until recently, when I came across few apps which requests user to turn on their custom accessibility service in order to work properly. To my surprise, these apps are in no way related to aiding accessibility for visual or physical impaired people. So I started looking into details of accessibility service. I will be sharing my findings in a series of two blogs.

This post explains what accessibility service is and how can we make our apps accessible. Next post will talk about creating custom accessibility services.

What are Accessibility services?

Accessibility services are a feature of Android framework designed to provide alternative navigation feedback to the user. These services run in the background and receive callbacks from the system when AccessibilityEvents are fired. These events are sent by the system when something notable happens in the user interface, for example, the focus has changed, a button has been clicked, etc.

We, as developers should make our apps accessible to all, for greater reachability. Below are a few strategies which would assist us in making accessible applications:

1. Adding content descriptions

contentDescriptions are labels given to UI elements which will be read out loud when user enables accessibility service like TalkBack.

One can add it in xml

or programmatically

paymentButton.setContentDescription(“Make Payment”);

2. Enable focus navigation

Most of the apps have touchscreen as the only available mode of navigation but by enabling focus navigation in our apps we can let users use D-pad (Directional Pad) or external devices like keyboards or mouse to navigate through the app.
To implement this, one should set android:focusable attribute for every UI control to true and to enable user to navigate using direction keys, one should provide
android:nextFocusUp, android:nextFocusDown, android:nextFocusLeft and android:nextFocusRight. Now, when user is on an element and uses direction key, respective element will be focused.

For example, let us consider a view having four buttons as shown in the screenshot below. To enable user to navigate among these buttons using D-Pad or external controllers we have to add nextFocus element for each direction.
dpad_demo
Here is the gist of code :
Corresponding style xml:

The demo application for this example can be found here.

3. Fire accessibility events from custom views:

Android framework fires AccessibilityEvents whenever there is a change of focus in UI elements. Depending on the specifics of our custom views, we should also fire respective AccessibilityEvents to make our app completely accessible.

For example, here is a custom view which comprises of an ImageView and two TextViews.

When ImageView is clicked the current location of the device is accessed and address of that location obtained by reverse geocoding is displayed on one of the TextViews. The other TextView is used to display a static text.

location_selector_view

To make this component accessible, AccessibilityEvent should be sent like this:

This was all about making our apps accessible. In next post I will explain about making custom accessibility services.

Stay tuned!