A TTS initialization error was observed in the following scenarios, which is too random.
The TTS engine is installed, a set of votes is present, and tts examples can be reproduced from the accessibility parameters.
Initialization of TTS is not performed randomly on the same device where it was previously initialized and played.
This problem was observed in different devices (One plus, Asus, Samsung) and different versions of the Android OS.
Code snippet:
public class TTSHandler implements OnInitListener {
public EPUBReader context;
private TextToSpeech tts;
private HashMap<String, String> ttsMap;
private boolean isTtsPlaying = false,shouldResume = false,initialised = false,
ttsModeEnabled = false;
private String textToRead;
private GoogleVersionPreferences mSharedPreferences;
private AudioManager mAudioManager;
@SuppressWarnings("deprecation")
public TTSHandler(EPUBReader context){
this.context = context;
tts = new TextToSpeech(context,this);
}
@Override
public void onInit(int status) {
Log.d("TTS", "onInit called");
if(status == TextToSpeech.SUCCESS){
initialised = true;
Log.d("TTS", "initialised success: status = "+status);
initTTSComponents();
}else{
initialised = false;
Log.d("TTS", " initialised failed: status ="+status);
}
}
public void readText(String text){
if(text!=null){
textToRead = text;
}
ttsMap = new HashMap<String, String>();
ttsMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, textToRead);
isTtsPlaying = true;
context.runOnUiThread(new Runnable(){
@Override
public void run() {
context.toggleTtsIcons();
}
});
tts.speak(textToRead,0, ttsMap);
}
public void playPauseReading(){
context.lockOrientationChange();
AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int volume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
if(isTtsPlaying){
isTtsPlaying = false;
shouldResume = true;
tts.stop();
}else{
isTtsPlaying = true;
if(shouldResume){
shouldResume = false;
requestAudioFocusForTTS();
JavaScriptInterface.loadJavascript("javascript:resumeUsingTts()", context.getEPUBReaderFragment().getWebview());
}else{
requestAudioFocusForTTS();
if(volume <= 1){
Toast.makeText(context,context.getResources().getString(R.string.tts_volume_alert), 300).show();
}
int dir = mSharedPreferences.getEpubNavigationSetting(context.bookId);
JavaScriptInterface.loadJavascript("javascript:playFromRange("+dir+")", context.getEPUBReaderFragment().getWebview());
}
}
context.toggleTtsIcons();
}
public void stopReading(){
if(tts !=null && ttsModeEnabled){
isTtsPlaying = false;
shouldResume = false;
ttsModeEnabled = false;
tts.stop();
Toast.makeText(context,context.getResources().getString(R.string.tts_stop) , 300).show();
JavaScriptInterface.loadJavascript("javascript:stopUsingTts()",
context.getEPUBReaderFragment().getWebview());
abandonAudioFocus();
context.runOnUiThread(new Runnable(){
@Override
public void run() {
context.toggleControlPanel(false);
context.unlockOrientationChange();
context.invalidateOptionsMenu();
}
});
}
}
public boolean isReading(){
if(tts.isSpeaking()){
return true;
}
return false;
}
public void stopReadingOnEndOfChapter(){
Log.d("TTS", "stopReadingOnEndOfChapter");
shouldResume = false;
isTtsPlaying = false;
ttsModeEnabled = false;
abandonAudioFocus();
context.runOnUiThread(new Runnable(){
@Override
public void run() {
context.toggleControlPanel(false);
context.unlockOrientationChange();
context.invalidateOptionsMenu();
Toast.makeText(context,context.getResources().getString(R.string.end_of_chapter) , 300).show();
}});
}
public void stopOnNoContent(){
Toast.makeText(context,context.getResources().getString(R.string.tts_no_content) , 300).show();
shouldResume = false;
isTtsPlaying = false;
ttsModeEnabled = false;
abandonAudioFocus();
context.runOnUiThread(new Runnable(){
@Override
public void run() {
context.toggleControlPanel(false);
context.unlockOrientationChange();
context.invalidateOptionsMenu();
}});
}
public void stopTtsOnLinks(){
if(isReading() || shouldResume)
Toast.makeText(context,context.getResources().getString(R.string.tts_stop) , 300).show();
shouldResume = false;
isTtsPlaying = false;
ttsModeEnabled = false;
tts.stop();
context.toggleControlPanel(false);
context.unlockOrientationChange();
abandonAudioFocus();
}
public void shutDownTTS(){
if(tts !=null){
tts.shutdown();
}
}
public void setSpeechRate(int value){
switch(value){
case 0:
tts.setSpeechRate((float)0.1);
break;
case 1:
tts.setSpeechRate((float)0.5);
break;
case 2:
tts.setSpeechRate((float)1);
break;
case 3:
tts.setSpeechRate((float)1.5);
break;
case 4:
tts.setSpeechRate((float)2);
break;
}
}
public void playNext(){
isTtsPlaying = false;
tts.stop();
JavaScriptInterface.loadJavascript("javascript:readNext()",context.getEPUBReaderFragment().getWebview());
}
public void playPrevious(){
isTtsPlaying = false;
tts.stop();
JavaScriptInterface.loadJavascript("javascript:playPrevious()",context.getEPUBReaderFragment().getWebview());
}
private void initTTSComponents(){
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
tts.setSpeechRate(1);
mSharedPreferences = GoogleVersionPreferences.getGoogleAppVersion(context);
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
Log.d("TTS", "onStart:"+utteranceId);
}
@Override
public void onError(String utteranceId) {
Log.d("TTS", "onError ID:"+utteranceId);
}
@Override
public void onDone(String utteranceId) {
Log.d("BUG", "onDone, isTtsPlaying:"+isTtsPlaying);
if(isTtsPlaying){
JavaScriptInterface.loadJavascript("javascript:readNext();",
((EPUBReader) context).getEPUBReaderFragment().getWebview());
}
}
});
}
private void requestAudioFocusForTTS(){
mAudioManager.requestAudioFocus(null,AudioManager.STREAM_MUSIC , AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE);
}
private void abandonAudioFocus(){
mAudioManager.abandonAudioFocus(null);
}
public void setisTtsPlaying(boolean value){
isTtsPlaying = value;
}
public boolean isTtsPlaying(){
return isTtsPlaying;
}
public void setshouldResume(boolean value){
shouldResume = value;
}
public boolean shouldResume(){
return shouldResume;
}
public boolean isTtsInitialised(){
return initialised;
}
public boolean ttsModeEnabled(){
return ttsModeEnabled;
}
public void setttsModeEnabled(boolean value){
ttsModeEnabled = value;
}
}
Note: collected logs:
For Samsung device (TabS 10.5 OS: 5.0.2): E / SamsungTTS (20259): onLoadLanguage () - SamsungTTS is not ready yet.
For one plus one (OS: 6.0.1):
08-08 18: 54: 53.112: W/TextToSpeech (22946): : TTS
08-08 18: 56: 15.869: I/TextToSpeech (22946): com.google.android.tts
08-08 18: 56: 16.060: I/TextToSpeech (22946): ComponentInfo {com.google.android.tts/com.google.android.tts.service.GoogleTTSService}