Start Android TTS from Broadcast Receiver or Service

两盒软妹~` 提交于 2019-11-30 16:39:25

It would help to see your TTS code to make it easier for people to help you. Since I already have TTS working in a BroadcastReceiver, here's an example trimmed down from my code.

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;
    }
}

Start the TTS service at the point in your BroadcastReceiver where you want it to speak:

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

I hope this helps someone if not the asker (I'm sure he got it working by now).

Niza Siwale

you can also try this,if the text to be spoken is coming from a broadcast listener.first create a service

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();
    }
}}

then create the listener where you're insert your text

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);

    }
}

make sure you start the service before you use the tts engine and also check if a tts engine is available

Ashish Sahu

Its working for me (just add on mainfest permision)

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);
  }
}

Android TTS is a bounded service. Broadcast receiver has a limited context and can't bind himself to any service. However, It can START a service. All the examples shown here are of services that starting the TTS engine and of receiver that starts them. You can also do it with activity but if you don't need UI a service is better. I just think it's a good idea to understand how it works and why is works. Good luck.

Using Kotlin, the above answers can be re-written as:

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
    }
}

And in the Manifest:

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

<service android:name=".TTS" />

Android-O onwards using service for things like this has background restrictions. One can use JobIntentService to achieve the same as shown here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!