android - 如何在 IntentService 中运行 Android TTS

标签 android text-to-speech logcat intentservice

我查看了几个询问如何从服务运行 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 会报告类似以下内容:“说话失败:未绑定(bind)到 tts 引擎”。

有没有办法让 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");
    }
}

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

最佳答案

您没有显式调用onInit()。一旦调用 onHandleIntent 方法,IntentService 就会被销毁。确保您在 onHandleIntent 方法中完成所有工作。

来自文档的onHandleIntent( Intent Intent ):

在工作线程上调用此方法并处理请求。一次仅处理一个 Intent,但处理发生在独立于其他应用程序逻辑运行的工作线程上。因此,如果此代码需要很长时间,它将阻止对同一 IntentService 的其他请求,但不会阻止其他任何请求。当所有请求都处理完毕后,IntentService 会自行停止,因此您不应调用 stopSelf()。

关于android - 如何在 IntentService 中运行 Android TTS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17914661/

相关文章:

Android - 按钮背景颜色缩小按钮的高度

Android TTS 和口型同步

Android Text to Speech 在手机响铃时被破坏

android - 在我的 Android 应用程序中的多个不同 Activity 中重复使用 TTS-Object

android -/dev/log/main 未找到

android - 如何在 Android 的 TextView 中打印完整的 logcat 历史记录?

java - 如何以编程方式设置广播接收器属性?

java - 如何从浏览器获取当前URL

android - 在android中的imageview中加载的图像的阴影效果

Java 记录器更好的格式化