Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there way to make talkback speak?

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...

like image 414
Initiator Avatar asked Sep 02 '25 06:09

Initiator


2 Answers

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);
}
like image 136
Hugo Allexis Cardona Avatar answered Sep 04 '25 20:09

Hugo Allexis Cardona


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.

like image 32
Carter Hudson Avatar answered Sep 04 '25 20:09

Carter Hudson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!