簡體   English   中英

使用服務設置警報時未調用onReceive

[英]onReceive not being called when setting an Alarm using Service

我一直在遵循一些教程來創建警報,當onRecieve()方法觸發時,我將使用TextToSpeech API講話。 通過這樣做,我發現在擴展BroadcastReciever時無法初始化TextToSpeech,但是找到了一個使用Service而不是BroadcastReciever的教程。

問題在於,永遠不會調用onRecieve()方法,並且不會顯示任何錯誤,表明未正確設置警報。

以下是我在MainActivity類中用於設置Alarm的方法。

protected void setAlarm() {

      Long time = timeTillAlarm;
      Log.v(TAG, "Time til Alarm = " + time);

    // create an Intent and set the class which will execute when Alarm triggers, here we have
    // given AlarmReciever in the Intent, the onRecieve() method of this class will execute when alarm triggers 
    Intent intentAlarm = new Intent(MainActivity.this, AlarmReciever.class);
    PendingIntent pIntent = PendingIntent.getService(this, 1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);

    // create the object
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    //set the alarm for particular time
    alarmManager.set(AlarmManager.RTC_WAKEUP, time, pIntent);


}

下面是我的AlarmReciever類:

public class AlarmReciever extends Service implements TextToSpeech.OnInitListener{
 private static final String TAG = "DEBUG";
 private TextToSpeech tts;
 private String spokenText;

 public AlarmReciever()
 {

 }

 public void onCreate() {
     tts = new TextToSpeech(this, this);
     spokenText = "Hello Kyle. Wake up now, it is a lovely day!";
     Log.v(TAG, "Alarm Text: " + spokenText);
     //speakOut();

 }

 public void onReceive(Context context, Intent intent)
 {  
    Log.v(TAG, "Recieved Alarm"); 
    speakOut();
 }

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

  @Override
     public void onInit(int status) {
      Log.v(TAG, "TTS Initialised");
         if (status == TextToSpeech.SUCCESS) {
             int result = tts.setLanguage(Locale.UK);
             if (result != TextToSpeech.LANG_MISSING_DATA && result != TextToSpeech.LANG_NOT_SUPPORTED) {
                // Log.v(TAG, "SPEAKING IN INIT");
                  //  tts.speak(spokenText, TextToSpeech.QUEUE_FLUSH, null);
             }
         }

     }

  @Override
    public void onDestroy() {
        // Don't forget to shutdown tts!
        if (tts != null) {
            tts.stop();
            tts.shutdown();
        }
        super.onDestroy();
    }

  private void speakOut() {
        Log.v(TAG, "SPEAKING");
        tts.speak(spokenText, TextToSpeech.QUEUE_FLUSH, null);
    } }

任何與這個問題的幫助將不勝感激:)

有些事情可能出錯了:

  1. 您是否已將AlarmReceiver聲明為Android Manifest.xml? (拼寫正確嗎?) <receiver android:name=”path.to.package.AlarmReceiver”></receiver>

  2. 您是否設置了正確的請求代碼? 那花了我幾個小時:請求廣播時,必須提供請求代碼。 如果我還沒有發現它的用途,請嘗試將其設置為任意隨機數。 例如

    PendingIntent pIntent = PendingIntent.getService(this,564864421,intentAlarm,PendingIntent.FLAG_UPDATE_CURRENT);

    當我將其設置為0時,它確實在一個示例項目中起作用(只有一個活動和警報),但是當我將其集成到實際交易中(15個活動,服務等)時,它就不再起作用。 這里解釋了requestCode的目的。

  3. 確保您的服務足夠長的喚醒時間:AlarmManager僅調用onReceive,但不獲取喚醒鎖-您必須自己處理喚醒鎖。 我在這里使用WakefulBroadcastReceiver,因為它就是這樣做的。 如果使用它(或喚醒鎖),請確保您的清單中有此文件: <uses-permission android:name="android.permission.WAKE_LOCK" />

最后,這是我的工作示例:

public class Alarm extends WakefulBroadcastReceiver {

    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;

    @Override
    public void onReceive(Context context, Intent intent) {   
        Intent service = new Intent(context, AlarmService.class);
        Log.d("AlarmService", "Alarm received");

        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, service);
    }

    @SuppressLint("NewApi")
    public void setAlarm(Context context, long inMillis) {
        boolean alarmUp = PendingIntent.getBroadcast(context, 0, new Intent(context, Alarm.class), PendingIntent.FLAG_NO_CREATE) != null;
        if (alarmUp)
            Log.d("AlarmService", "Alarm is already up");
        else
            Log.d("AlarmService", "Alarm is NOT active");

        alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, Alarm.class);
        alarmIntent = PendingIntent.getBroadcast(context, 5468461, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        alarmMgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+inMillis, alarmIntent);

        Log.d("AlarmService", "alarm set");
    }

    public void cancelAlarm(Context context) {
        // If the alarm has been set, cancel it.
        if (alarmMgr!= null) {
            alarmMgr.cancel(alarmIntent);
        }
        Log.d("AlarmService", "alarm canceled");    
    }
}

<receiver android:name="path.to.Alarm" />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM