我有一项服务,当用户进入某个地理区域时我必须说话(由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;
}
答案 0 :(得分:0)
你有时间问题。
当您通过Service
启动PendingIntent
时,Android会创建Service
的实例,然后拨打onCreate()
,然后拨打onStartCommand()
。您正试图在onStartCommand()
中使用TTS引擎说话。但TTS引擎没有足够的时间进行初始化。
要让引擎在使用之前有足够的时间进行初始化,您需要修改架构。
使用private boolean
变量来跟踪初始化是否完成。如果一切都成功,请将其设置为true
中的onInit()
。
在onStartCommand()
中,通过检查private boolean
来检查TTS初始化是否已完成。如果有,你可以立即发言。如果没有,您需要启动一个后台Thread
循环,等待,检查标志等,直到初始化完成。只有这样,你真的可以使用TTS引擎发言吗。