DISCLAIMER: You have to be exceptionally careful with this solution! Overriding TTS behavior of TalkBack is very, VERY sketchy. There are many edge cases that could make this behavior awkward, unwieldy and very bad from an accessibility perspective. This solution should only be used when the style of the announcement is behavior specific to the app and REQUIRED functionality. Otherwise this solution breaks all sorts of WCAG 2.0 success criteria regarding compatibility with user agents and is generically a terrible idea from an accessibility/usability standpoint!
In many cases when I see questions like this, I'm hesitant to provide an answer, so as not to give developers a tool that they don't understand. PLEASE PLEASE PLEASE DO NOT DO THIS in a typical application, it is a terrible idea. That being said, I believe this particular situation calls for it, and that this is a very clean solution given the circumstances. In the on create of your activity do the following:
findViewById(android.R.id.content).setAccessibilityDelegate(new View.AccessibilityDelegate() {
private TextToSpeech mTts = new TextToSpeech(MainActivity.this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
mTts.setLanguage(new Locale("es"));
//Probably other things you should do to ensure TTS is initialized before requesting it speaks something.
}
});
private boolean isSpanishView(View view) {
return true;
}
@Override
public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
switch (event.getEventType()) {
case AccessibilityEvent.TYPE_ANNOUNCEMENT:
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
if (isSpanishView(child)) {
String speakableText = null;
if (event.getText() != null) {
speakableText = event.getText().toString();
} else if (event.getContentDescription() != null) {
speakableText = event.getContentDescription().toString();
}
if (speakableText != null) {
mTts.speak(speakableText.toString(), TextToSpeech.QUEUE_ADD, null);
//Prevent the default propagation of this event, have have handled it.
return false;
}
}
}
default:
return super.onRequestSendAccessibilityEvent(host, child, event);
}
}
});
Basically what we have said here is attach an accessibility delegate to the root view of our activity. Look at ALL of the accessibility events that are popping up. Check to see that it is an event that announces something. If it is, check to see that it is a view that contains Spanish text. If it is, allow our Spanish TTS Engine to announce it, instead of allowing the vent to propagate. In all other circumstances let android do its thing.