2

我查看了几个关于从服务运行 TTS 的线程(抱歉,不记得哪些线程),但没有一个有帮助。

IntentService 启动得很好,但是在 onInit() 运行之前它就被破坏了,我认为这就是导致这个 logcat 的原因:

    07-28 18:58:24.716    2305-2305/me.arthurtucker.alfredjr D/MainActivity: onPrefChange
07-28 18:58:24.786    2305-2305/me.arthurtucker.alfredjr D/MainActivity: made new intent
07-28 18:58:24.794    2305-2305/me.arthurtucker.alfredjr D/MainActivity: started service
07-28 18:58:25.044    2305-2305/me.arthurtucker.alfredjr I/SpeachService: onCreate() ran
07-28 18:58:25.255    2305-2573/me.arthurtucker.alfredjr I/TextToSpeech: Sucessfully bound to com.google.android.tts
07-28 18:58:25.255    2305-2573/me.arthurtucker.alfredjr I/SpeachService: onHandleIntent ran
07-28 18:58:25.255    2305-2305/me.arthurtucker.alfredjr W/TextToSpeech: stop failed: not bound to TTS engine
07-28 18:58:25.255    2305-2305/me.arthurtucker.alfredjr W/TextToSpeech: shutdown failed: not bound to TTS engine
07-28 18:58:25.255    2305-2305/me.arthurtucker.alfredjr I/SpeachService: onDestroy() ran
07-28 18:58:25.286    2305-2305/me.arthurtucker.alfredjr E/ActivityThread: Service me.arthurtucker.alfredjr.SpeechService has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@37ad3e10 that was originally bound here
        android.app.ServiceConnectionLeaked: Service me.arthurtucker.alfredjr.SpeechService has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@37ad3e10 that was originally bound here
        at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
        at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
        at android.app.ContextImpl.bindService(ContextImpl.java:1437)
        at android.app.ContextImpl.bindService(ContextImpl.java:1426)
        at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
        at android.speech.tts.TextToSpeech.connectToEngine(TextToSpeech.java:627)
        at android.speech.tts.TextToSpeech.initTts(TextToSpeech.java:597)
        at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:553)
        at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:527)
        at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:512)
        at me.arthurtucker.alfredjr.SpeechService.onHandleIntent(SpeechService.java:37)
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.os.HandlerThread.run(HandlerThread.java:60)

我尝试在 onCreate()、onHandleIntent() 和现在的 onInit() 中运行 sayString()。在 onCreate() 或 onHandleIntent() 中,logcat 会报告类似:“speak failed: not bound to tts engine”。

有没有办法让 IntentService 在销毁之前等待 onInit() 运行?

我的代码如下。

    public class SpeechService extends IntentService implements TextToSpeech.OnInitListener, TextToSpeech.OnUtteranceCompletedListener {
    private static TextToSpeech myTTS;
    private Main mActivity;
    private static final String TAG = "SpeachService";
    //private String msg;

    public SpeechService() {
        super("SpeechService");
    }

    @Override
    public void onCreate() {
        mActivity = new Main();
        super.onCreate();
        Log.i(TAG, "onCreate() ran");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Intent checkTTSIntent = new Intent();
        checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        myTTS = new TextToSpeech(this, this);
        //String msg = intent.getStringExtra("imsg");
        Log.i(TAG, "onHandleIntent ran");
    }

    public void sayString(String string) {
        if (myTTS != null) {
            if (mActivity.mEnabled) {
                HashMap<String, String> hashMap = new HashMap<String, String>();
                hashMap.put(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true");
                myTTS.speak(string, 1, hashMap);
            } else {
                myTTS.speak(string, 1, null);
            }
        }

        Log.i(TAG, "sayString() ran");
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        if (myTTS != null) {
            myTTS.stop();
            myTTS.shutdown();
        }
        super.onDestroy();
        Log.i(TAG, "onDestroy() ran");
    }

    @Override
    public void onInit(int initStatus) {
        if (initStatus == TextToSpeech.SUCCESS) {
            if (myTTS.isLanguageAvailable(Locale.UK) == TextToSpeech.LANG_AVAILABLE) {
                myTTS.setLanguage(Locale.UK);
            }
            sayString("IT WORKS");
        } else if (initStatus == TextToSpeech.ERROR) {
            mActivity.makeToast("Failed to start Text-to-Speech Service", true);
        }
        Log.i(TAG, "onInit() ran");
    }

    @Override
    public void onUtteranceCompleted(String s) {
        stopSelf();
        Log.i(TAG, "onUtteranceCompleted() ran");
    }
}

我愿意尝试一些完全不同的方法,只要它做类似的事情。

4

1 回答 1

2

你没有onInit()明确地打电话。IntentService一旦onHandleIntent方法被调用就被销毁。确保您按照onHandleIntent方法完成所有工作。

文档中的 onHandleIntent(Intent intent)

This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().

于 2013-07-29T01:55:22.013 回答