Question

While making my application accessible, I have a problem - there's no way to make it SPEAK!!

By referencing google's library, I make

public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event)

on my customized view and I get right event message - I checked it by using Log.d
However, there's no way to make talkback to speak...
My Application runs from API8 so I can't use also,

onPopulateAccessibilityEvent()

Am I thinking wrong? Please somebody help me...

Was it helpful?

Solution 3

If you want it to speak, use the TextToSpeech API. It takes a string and reads it outloud.

OTHER TIPS

For people looking to implement @Carter Hudson's code in Java (don't judge me cause I'm still not using Kotlin in 2019):

AccessibilityManager accessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain();
accessibilityEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);

accessibilityEvent.getText().add("Text to be spoken by TalkBack");
if (accessibilityManager != null) {
    accessibilityManager.sendAccessibilityEvent(accessibilityEvent);
}

I needed to announce when a button became visible after reloading a RecyclerView's items with a new dataset. RecyclerView being a framework view, it supports talkback / accessibility out-of-the-box. After loading new data, talkback announces "showing items x through y of z" automatically. Utilizing the TTS API to solve the use case I mentioned introduces the following pitfalls:

  • TTS instance initialization and management is cumbersome and questionable for the following reasons:
    • Managing TTS instance lifecycle with onInit listener
    • Managing Locale settings
    • Managing resources via shutdown() ties you to an Activity's lifecycle per documentation
    • An Activity's onDestroy is not guaranteed to be called, which seems like a poor mechanism for calling shutdown() in order to deallocate TTS resources.

An easier, more maintainable solution is to play nicely with TalkBack and utilize the Accessibility API like so:

class AccessibilityHelper {
    companion object {
        @JvmStatic
        fun announceForAccessibility(context: Context, announcement: String) {
            context
                .getSystemService(ACCESSIBILITY_SERVICE)
                .let { it as AccessibilityManager }
                .let { manager ->
                    AccessibilityEvent
                        .obtain()
                        .apply {
                            eventType = TYPE_ANNOUNCEMENT
                            className = context.javaClass.name
                            packageName = context.packageName
                            text.add(announcement)
                        }
                        .let {
                            manager.sendAccessibilityEvent(it)
                        }
                }
        }
    }
}

Call the above from wherever you need (I added a method to my base activity that forwards to the helper). This will insert the announcement into the queue of messages for TalkBack to announce out loud and requires no handling of TTS instances. I ended up adding a delay parameter and mechanism into my final implementation to separate these events from ongoing ui-triggered events as they sometimes tend to override manual announcements.

announceForAccessibility method defined in the View class probably serves the purpose here. It was introduced in API level 16. More details here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top