TextToSpeech using WakefulBroadcastReceiver

312 views Asked by At

How can I use the the Text To Speech functionality onPause method using WakefulBroadcastReceiver I made the following classes for the purpose: I am using Receiver for the GCM Push Notification and this code works fine onReceive method but when app is onPause state and the notification dispaly in NotificatioManager at that moment app crashed, help me to sort this problem

GcmBroadcastReceiver

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

Context mContext;

@Override
public void onReceive(Context context, Intent intent)
{
            mContext = context;
            ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
            if (!services.get(0).topActivity.getPackageName().toString().equalsIgnoreCase(context.getPackageName().toString()))
            {
                Speaker speaker = new Speaker(mContext);
                speaker.allow(true);
                speaker.speak("asdas","asdas");
            }
}
}

Speaker.class

public class Speaker implements OnInitListener {

private TextToSpeech tts;
private boolean ready = false;
private boolean allowed = false;

public Speaker(Context context){
    tts = new TextToSpeech(context, this);
}
public void allow(boolean allowed){
    this.allowed = allowed;
}

@Override
public void onInit(int status) {
    if(status == TextToSpeech.SUCCESS){
        tts.setLanguage(new Locale("en-AU"));
        ready = true;
    }
    else{
        ready = false;
    }
}
public void speak(String welcomeMessage, String body){

    if(allowed) {
        HashMap<String, String> hash = new HashMap<String,String>();
        hash.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
                String.valueOf(AudioManager.STREAM_NOTIFICATION));
        tts.setSpeechRate((float) 0.8);
        tts.speak(welcomeMessage, TextToSpeech.QUEUE_ADD, hash);
        tts.playSilence(500, TextToSpeech.QUEUE_ADD, null);
        tts.speak(body, TextToSpeech.QUEUE_ADD, hash);
    }
}
}

Following exception i have faced

Caused by: android.content.ReceiverCallNotAllowedException:
BroadcastReceiver components are not allowed to bind to services
at android.app.ReceiverRestrictedContext.bindService(ContextImpl.java:173)
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 sss.sss.sss.Speaker.<init>(Speaker.java:20)
at sss.sss.sss.GcmBroadcastReceiver.onReceive(GcmBroadcastReceiver.java:47)
1

There are 1 answers

0
Hoan Nguyen On

You should start your service in onReceive passing the message to speak

@Override
public void onReceive(Context context, Intent intent)
{
     intent.setAction("speak");
     intent.putExtra("welcome_message", "asdas");
     intent.putExtra("body", "asdas");
     startService(intent.setComponent(new ComponentName(context.getPackageName(),
                MyService.class.getName())));
      // Where MyService is the service that you implements TTS
}

Then in the service class

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    if (intent != null)
    {
        String action = intent.getAction();
        if ("speak".equals(action))
        {
             // check if TTS is initialize if so speak the extra
             // otherwise save the extra to class members and when onInit is called
             // check if these class members are null then speak 
        }
    }
}