1

我正在为 Android 应用程序工作文本到语音。我对找到一种在完成 Text to Speech 时调用的方法感到困惑。我尝试调用以下方法,但未调用完成,请查看以下代码并建议我。

 tts= new TextToSpeech(MainActivity.this, new OnInitListener() {

         @Override
         public void onInit(int status) {

             tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {

                @Override
                public void onUtteranceCompleted(final String utteranceId) {
                            System.out.println("Completed");

                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                        //UI changes
                        }
                    });
                }
            });

         }
        });

请给我建议。我正在使用 API 级别 17。


编辑:

最低 API 级别为 12;

我在控制台中收到以下错误:

01-30 09:19:14.149: E/ActivityThread(660): Service com.android.exchange.ExchangeService

    has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@40ce0ef0 that was originally bound here
01-30 09:19:14.149: E/ActivityThread(660): android.app.ServiceConnectionLeaked: Service com.android.exchange.ExchangeService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@40ce0ef0 that was originally bound here
01-30 09:19:14.149: E/ActivityThread(660):  at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
01-30 09:19:14.149: E/ActivityThread(660):  at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
01-30 09:19:14.149: E/ActivityThread(660):  at android.app.ContextImpl.bindService(ContextImpl.java:1418)
01-30 09:19:14.149: E/ActivityThread(660):  at android.app.ContextImpl.bindService(ContextImpl.java:1407)
01-30 09:19:14.149: E/ActivityThread(660):  at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:157)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:145)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.emailcommon.service.AccountServiceProxy.getDeviceId(AccountServiceProxy.java:116)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.exchange.ExchangeService.getDeviceId(ExchangeService.java:1249)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.exchange.ExchangeService$7.run(ExchangeService.java:1856)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:551)
01-30 09:19:14.149: E/ActivityThread(660):  at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:549)
01-30 09:19:14.149: E/ActivityThread(660):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-30 09:19:14.149: E/ActivityThread(660):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-30 09:19:14.149: E/ActivityThread(660):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-30 09:19:14.149: E/ActivityThread(660):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-30 09:19:14.149: E/ActivityThread(660):  at java.lang.Thread.run(Thread.java:856)
01-30 09:19:14.169: E/StrictMode(660): null
01-30 09:19:14.169: E/StrictMode(660): android.app.ServiceConnectionLeaked: Service com.android.exchange.ExchangeService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@40ce0ef0 that was originally bound here
01-30 09:19:14.169: E/StrictMode(660):  at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
01-30 09:19:14.169: E/StrictMode(660):  at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
01-30 09:19:14.169: E/StrictMode(660):  at android.app.ContextImpl.bindService(ContextImpl.java:1418)
01-30 09:19:14.169: E/StrictMode(660):  at android.app.ContextImpl.bindService(ContextImpl.java:1407)
01-30 09:19:14.169: E/StrictMode(660):  at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:157)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:145)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.emailcommon.service.AccountServiceProxy.getDeviceId(AccountServiceProxy.java:116)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.exchange.ExchangeService.getDeviceId(ExchangeService.java:1249)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.exchange.ExchangeService$7.run(ExchangeService.java:1856)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:551)
01-30 09:19:14.169: E/StrictMode(660):  at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:549)
01-30 09:19:14.169: E/StrictMode(660):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-30 09:19:14.169: E/StrictMode(660):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-30 09:19:14.169: E/StrictMode(660):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-30 09:19:14.169: E/StrictMode(660):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-30 09:19:14.169: E/StrictMode(660):  at java.lang.Thread.run(Thread.java:856)
4

5 回答 5

6

问题不在于onUtteranceCompletefunction ,它很可能被调用,但您正在尝试将输出打印到System.out,请android.utils.Log("tag", "success")改用,看看会发生什么。

此外,您需要onUtteranceComplete在调用tts.speak方法之前设置 UtteranceID 才能开始工作。所以总结一下:

            TextToSpeech tts= new TextToSpeech(MainActivity.this, new OnInitListener() {

         @Override
         public void onInit(int status) {

             tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {

                @Override
                public void onUtteranceCompleted(final String utteranceId) {
                            System.out.println("Completed");

                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                        //UI changes
                        }
                    });
                }
            });

         }
    });
    Map<String,String> ttsParams = new HashMap<String, String>();
    ttsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
            MainActivity.this.getPackageName());

    mTts.speak(text, TextToSpeech.QUEUE_FLUSH, ttsParams);

并且您得到的异常与该方法无关onUtteranceComplete,如果是因为 tts 引擎很可能您在完成活动时没有请求销毁您的实例。

修复那个添加

@Override
onDestroy(){
super.onDestroy();
mTts.shutdown(); //mTts is your TextToSpeech Object
}

到你的活动课

于 2013-01-30T09:27:03.907 回答
2

简单的方法

textToSpeech=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
    @Override
    public void onInit(int status) {
        if (status==TextToSpeech.SUCCESS){
            int result=textToSpeech.setLanguage(Locale.ENGLISH);

            if (result==TextToSpeech.LANG_MISSING_DATA||result==TextToSpeech.LANG_NOT_SUPPORTED){
                Log.i("TextToSpeech","Language Not Supported");
            }

            textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                @Override
                public void onStart(String utteranceId) {
                    Log.i("TextToSpeech","On Start");
                }

                @Override
                public void onDone(String utteranceId) {
                    Log.i("TextToSpeech","On Done");
                }

                @Override
                public void onError(String utteranceId) {
                    Log.i("TextToSpeech","On Error");
                }
            });

        }else {
            Log.i("TextToSpeech","Initialization Failed");
        }
    }
});

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    textToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH,null,TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
}
于 2019-11-16T20:48:07.717 回答
1

从 API 级别 15 开始,您必须使用setOnUtteranceProgressListener而不是setOnUtteranceCompletedListener

查看官方文档

于 2013-01-30T08:41:10.237 回答
0

试试这个:

if(tts.myTTS.isSpeaking())

你得到一个布尔值。

于 2017-04-11T23:54:22.390 回答
0

我发现“话语”是针对合成文件的。

对于说话我使用while(!utteranceDone){thread.sleep...}和这段代码:

                                brTTS = new BroadcastReceiver(){
                                public void onReceive(Context p1, Intent p2) {
                                    //Log.d(TAG,"TTS ACTION_TTS_QUEUE_PROCESSING_COMPLETED, p2.getAction()="+p2.getAction()+", ? "+TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
                                    if (p2.getAction().equals(TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED) && tts != null) {
                                        utteranceDone=true;
                                    }
                                }
                            };
                            registerReceiver(brTTS, new IntentFilter(TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED));
于 2017-05-10T14:28:38.037 回答