【问题标题】:Start Android TTS from Broadcast Receiver or Service从广播接收器或服务启动 Android TTS
【发布时间】:2010-10-05 03:47:11
【问题描述】:

我正在尝试让 TTS 在后台运行。但是,我从来没有听到任何声音。我有一个启动服务的广播接收器。我把我的 TTS 代码放在这两个里面,但它从不说话。我知道该方法正在被调用(我在其上设置了断点),但它仍然不起作用。

这是我的日志,但它似乎没有包含有关 TTS 服务的任何内容。

10-04 22:45:30.663: WARN/InputManagerService(209): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@4423df40
10-04 22:45:37.363: INFO/PollingManager(449): calculateShortestInterval(): shortest interval is 540000
10-04 22:45:37.413: INFO/TLSStateManager(449): org.apache.harmony.nio.internal.SocketChannelImpl@4400ece0: Wrote out 29 bytes of data with 0 bytes remaining.
10-04 22:45:38.043: ERROR/IMAPEmailService(480): Can't create default IMAP system folder Trash. Please reconfigure the folder names.
10-04 22:45:40.123: ERROR/EONS(303): EF_PNN: No short Name
10-04 22:45:41.543: ERROR/WMSTS(171): Month is invalid: 0
10-04 22:45:42.043: WARN/AudioFlinger(172): write blocked for 212 msecs, 24 delayed writes, thread 0xb998

提前谢谢大家!

【问题讨论】:

  • 你能说明你是如何初始化 tts 的吗?

标签: android android-service text-to-speech


【解决方案1】:

查看您的 TTS 代码有助于人们更轻松地为您提供帮助。由于我已经在 BroadcastReceiver 中使用了 TTS,下面是一个从我的代码中删减的示例。

public static class TTS extends Service implements TextToSpeech.OnInitListener, OnUtteranceCompletedListener {
    private TextToSpeech mTts;
    private String spokenText;

    @Override
    public void onCreate() {
        mTts = new TextToSpeech(this, this);
        // This is a good place to set spokenText
    }

    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            int result = mTts.setLanguage(Locale.US);
            if (result != TextToSpeech.LANG_MISSING_DATA && result != TextToSpeech.LANG_NOT_SUPPORTED) {
                mTts.speak(spokenText, TextToSpeech.QUEUE_FLUSH, null);
            }
        }
    }

    @Override
    public void onUtteranceCompleted(String uttId) {
        stopSelf();
    }

    @Override
    public void onDestroy() {
        if (mTts != null) {
            mTts.stop();
            mTts.shutdown();
        }
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}

在 BroadcastReceiver 中您希望它说话的位置启动 TTS 服务:

context.startService(new Intent(context, TTS.class));

如果不是提问者,我希望这对某人有所帮助(我相信他现在已经开始工作了)。

【讨论】:

  • 就像注释一样,要在创建服务时指定 speakText,请按照 this answer 覆盖 onStartCommand()
  • 这是一个非常好的答案,如果您能在清单文件中添加必须提及的服务以及如何终止此服务,我将不胜感激。
【解决方案2】:

如果要说的文本来自广播侦听器,您也可以试试这个。首先创建一个服务

public class MyTell extends Service implements OnInitListener{
   public MyTell() {
   }

   public static TextToSpeech mTts;

   @Override
   public IBinder onBind(Intent intent) {
       return null;
   }

   public void onStart(Intent intent, int startId) {
       // TODO Auto-generated method stub
       mPreferences = getSharedPreferences(Mysettings.PREF_NAME, Service.MODE_PRIVATE);

       pit = Float.parseFloat(mPreferences.getString("pit","0.8"));
       rate = Float.parseFloat(mPreferences.getString("rate","1.1"));
       mTts = new TextToSpeech(this, this);
       super.onStart(intent, startId);
   }

public void onInit(int status) {
    // TODO Auto-generated method stub
    if (status == TextToSpeech.SUCCESS) {
        if (mTts.isLanguageAvailable(Locale.UK) >= 0)

        Toast.makeText( MyTell.this,
                "Sucessfull intialization of Text-To-Speech engine Mytell ",
                Toast.LENGTH_LONG).show();
        mTts.setLanguage(Locale.UK);

        mTts.setPitch(pit);
        mTts.setSpeechRate(rate);

    } else if (status == TextToSpeech.ERROR) {
        Toast.makeText(MyTell.this,
                "Unable to initialize Text-To-Speech engine",
                Toast.LENGTH_LONG).show();
    }
}}

然后在您插入文本的位置创建侦听器

public class MyBroadCast extends BroadcastReceiver {
    public MyPop() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        //here is where you're use the service you created to speak the text
        MyTell.mTts.speak("Text to be spoken", TextToSpeech.QUEUE_FLUSH,null);

    }
}

确保在使用 tts 引擎之前启动服务,并检查 tts 引擎是否可用

【讨论】:

    【解决方案3】:

    它对我有用(只需添加 mainfest 权限)

    public class TES extends Service implements TextToSpeech.OnInitListener {
    
      private TextToSpeech tts;
    
      @Override
      public IBinder onBind(Intent arg0) {
        return null;
      }
    
      @Override
      public void onCreate() {
        super.onCreate();
      }
    
      @Override
      public void onDestroy() {
        // TODO Auto-generated method stub
        if (tts != null) {
            tts.stop();
            tts.shutdown();
        }
        super.onDestroy();
      }
    
      @Override
      public void onStart(Intent intent, int startId) {
        tts = new TextToSpeech(this, this);
        speakOut();
      }
    
      @Override
      public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
          int result = tts.setLanguage(Locale.US);
          if (result == TextToSpeech.LANG_MISSING_DATA
            || result == TextToSpeech.LANG_NOT_SUPPORTED) {
              Log.e("TTS", "This Language is not supported");
          }
          speakOut();
        } else {
          Log.e("TTS", "Initilization Failed!");
        }
      }
    
      private void speakOut() {
        tts.speak("its working", TextToSpeech.QUEUE_FLUSH, null);
      }
    }
    

    【讨论】:

      【解决方案4】:

      Android TTS 是一项有界服务。广播接收器的上下文有限,不能将自己绑定到任何服务。但是,它可以启动服务。这里显示的所有示例都是启动 TTS 引擎的服务和启动它们的接收器。 您也可以通过活动来完成,但如果您不需要 UI,则服务会更好。 我只是认为了解它的工作原理以及为什么有效是一个好主意。 祝你好运。

      【讨论】:

        【解决方案5】:

        使用 Kotlin,上面的答案可以重写为:

        Receiver:

        class MyReceiver : BroadcastReceiver() {
            val ttsService = Intent(context, TTS::class.java)
            context.startService(ttsService)
        }
        

        Service:

        class TTS : Service(), TextToSpeech.OnInitListener {
            private var mTts: TextToSpeech? = null
            private var spokenText: String? = null
        
            override fun onCreate() {
                mTts = TextToSpeech(this, this)
                // This is a good place to set spokenText
                spokenText = "Hello!.."
            }
        
            override fun onInit(status: Int) {
                if (status == TextToSpeech.SUCCESS) {
                   val result = mTts!!.setLanguage(Locale.US)
                    if (result != TextToSpeech.LANG_MISSING_DATA && result != TextToSpeech.LANG_NOT_SUPPORTED) {
                        Thread().run {
                            mTts!!.apply {
                                speak(spokenText, TextToSpeech.QUEUE_FLUSH, null, null)
                            }
                            Thread.sleep(10000)
                            stopSelf()
                        }
                    }
                } else if (status == TextToSpeech.ERROR) {
                   stopSelf()
                }
            }
        
            override fun onDestroy() {
               if (mTts != null) {
                    mTts!!.stop()
                    mTts!!.shutdown()
                }
                super.onDestroy()
            }
        
            override fun onBind(arg0: Intent): IBinder? {
                return null
            }
        }
        

        而在Manifest

        <receiver
            android:name=".MyReceiver">
            <intent-filter>
                <action android:name="android.intent.action.xxxx" />
            </intent-filter>
        </receiver>
        
        <service android:name=".TTS" />
        

        【讨论】:

        • 文字是只说一次还是重复?
        【解决方案6】:

        Android-O 及以上使用此类服务​​的服务有 background restrictions。可以使用 JobIntentService 来实现,如图here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多