Reputation: 55
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...
Upvotes: 3
Views: 3480
Reputation: 1413
Very this is tool, can use it everywhere with guard
public static void speak_loud(String str_speak) {
if (isGoogleTalkbackActive()) {
AccessibilityManager accessibilityManager = (AccessibilityManager) getDefaultContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain();
accessibilityEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
accessibilityEvent.getText().add(str_speak);
if (accessibilityManager != null) {
accessibilityManager.sendAccessibilityEvent(accessibilityEvent);
}
}
}
public static boolean isGoogleTalkbackActive() {
AccessibilityManager am = (AccessibilityManager) getDefaultContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
if (am != null && am.isEnabled()) {
List<AccessibilityServiceInfo> serviceInfoList = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN);
if (!serviceInfoList.isEmpty())
return true;
}
return false;
}
Upvotes: 0
Reputation: 3712
announceForAccessibility
method defined in the View class probably serves the purpose here. It was introduced in API level 16. More details here.
Upvotes: 0
Reputation: 1432
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);
}
Upvotes: 7
Reputation: 1263
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:
shutdown()
ties you to an Activity
's lifecycle per documentationshutdown()
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.
Upvotes: 4
Reputation: 93708
If you want it to speak, use the TextToSpeech API. It takes a string and reads it outloud.
Upvotes: 0