Reputation: 41
I have a duo lingo (English + Spanish) android application. I am implementing accessibility in my application, and I want the Talkback to read the Spanish words in Spanish and the English words in English. The English and Spanish words are going to be in separate Text views. My app locale is English and hence the Talkback + google text to speech engine are not reading the Spanish words in Spanish, they are read in English and more often their letters are read out (expected behavior).
Is there any work around or android recommended solution to achieve the same.
Ultimately I want the Talkback or the custom accessibility service to read out the English words in English and the Spanish words in Spanish.
Upvotes: 4
Views: 2271
Reputation: 15334
Google announced an update which allows you to specify the language you want text to be read aloud. An answer with links is provided here: https://stackoverflow.com/a/44461540/494879
Upvotes: 0
Reputation: 18860
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.
Upvotes: 1