“说话失败:没有绑定TTS引擎”服务内部

时间:2015-11-29 23:40:18

标签: android google-maps android-intent android-activity android-service

我有一项服务,当用户进入某个地理区域时我必须说话(由Geofence监控)。以下是我的代码:

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);
}

}

我收到错误:Speak failed not bound to TTS engine。这有什么不对?我绑定引擎到TextToSpeech。我正在绑定这样的服务:

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;
    }

1 个答案:

答案 0 :(得分:0)

你有时间问题。

当您通过Service启动PendingIntent时,Android会创建Service的实例,然后拨打onCreate(),然后拨打onStartCommand()。您正试图在onStartCommand()中使用TTS引擎说话。但TTS引擎没有足够的时间进行初始化。

要让引擎在使用之前有足够的时间进行初始化,您需要修改架构。

使用private boolean变量来跟踪初始化是否完成。如果一切都成功,请将其设置为true中的onInit()

onStartCommand()中,通过检查private boolean来检查TTS初始化是否已完成。如果有,你可以立即发言。如果没有,您需要启动一个后台Thread循环,等待,检查标志等,直到初始化完成。只有这样,你真的可以使用TTS引擎发言吗。