简体   繁体   中英

“speak failed: not bound to TTS engine” inside Service

I have a service where I have to speak when a user enters a geographical area(monitored by Geofence). Following is my code:

public class GeoIntentService extends Service implements TextToSpeech.OnInitListener {
private TextToSpeech engine;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate(){
    engine = new TextToSpeech(this,
            this  // OnInitListener
    );
    engine.setLanguage(Locale.ENGLISH);
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    if (!geofencingEvent.hasError()) {
        sendNotification(this, getTriggeringGeofences(intent));
    return Service.START_NOT_STICKY;
}
    return flags;
}

@Override
public void onDestroy() {
    while  (engine.isSpeaking()) {
        System.out.println("Hey engine is still speaking...");
    }
    if(engine!=null){
        engine.stop();
        engine.shutdown();
    }
    super.onDestroy();
}

@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {
        int result = engine.setLanguage(Locale.US);
        isInit = true;
        if (result == TextToSpeech.LANG_MISSING_DATA ||
                result == TextToSpeech.LANG_NOT_SUPPORTED) {
            Log.v("OnInit", "Language is not available.");
        } else {
            Log.v("OnInit","Language Set");
        }
    } else {
        Log.v("onInit", "Could not initialize TextToSpeech.");
    }

}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void sendNotification(Context context, String notificationText) {
    System.out.println("Time speak start: " + new Date(System.currentTimeMillis()));
    engine.speak("You are approaching Bus Stop " + notificationText,
            TextToSpeech.QUEUE_FLUSH, null, null);
    while (engine.isSpeaking()) {
        System.out.println("Hey engine is still speaking inside...");
    }
    stopSelf();
    engine.shutdown();
    System.out.println("Time speak end: " + new Date(System.currentTimeMillis()));
    //engine.shutdown();
}

private String getTriggeringGeofences(Intent intent) {
    GeofencingEvent geofenceEvent = GeofencingEvent.fromIntent(intent);
    List<Geofence> geofences = geofenceEvent
            .getTriggeringGeofences();

    String[] geofenceIds = new String[geofences.size()];

    for (int i = 0; i < geofences.size(); i++) {
        geofenceIds[i] = geofences.get(i).getRequestId();
    }

    return TextUtils.join(", ", geofenceIds);
}

}

I am getting error: Speak failed not bound to TTS engine . What's wrong here? I am binding engine to TextToSpeech. I am binding this service like this:

private PendingIntent createRequestPendingIntent() {
        if (mPendingIntent == null) {
            Log.v(TAG, "Creating PendingIntent");
            Intent intent = new Intent(mContext, GeoIntentService.class);
            mPendingIntent = PendingIntent.getService(mContext, 0, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
        }

        return mPendingIntent;
    }

You have a timing problem.

When your Service is started via PendingIntent , Android will create an instance of the Service , then call onCreate() and then call onStartCommand() . You are trying to speak using the TTS engine in onStartCommand() . But the TTS engine has not had enough time to initialize.

To give the engine enough time to initialize before you use it, you'll need to modify your architecture.

Use a private boolean variable to keep track of whether or not the initialization is complete. Set it to true in onInit() if everything is successful.

in onStartCommand() , check if the TTS initialization has completed by checking your private boolean . If it has, you can speak immediately. If not, you'll need to start a background Thread that loops, waiting a bit, checking the flag, etc., until the initialization has completed. Only then, can you actually use the TTS engine to speak.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM