2010-12-13 60 views
15

我目前正在嘗試編寫報警管理器,每天在指定的時間段內發出報警。首先,我檢查,看看用戶是否已爲這一天的報警設置:如何設置週期性AlarmManager每天執行代碼

​​

然後我去設置實際報警12,第二天的12:10之間熄滅:

 public static void setFutureAppointmentCheck(Context con) { 
    AlarmManager am = (AlarmManager) con 
    .getSystemService(Context.ALARM_SERVICE); 

    Date futureDate = new Date(new Date().getTime() + 86400000); 
    Random generator = new Random(); 

    futureDate.setHours(0); 
    futureDate.setMinutes(generator.nextInt(10)); 
    futureDate.setSeconds(0); 

    Intent intent = new Intent(con, FutureAppointmentReciever.class); 

    PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent, 
    PendingIntent.FLAG_ONE_SHOT); 

    am.set(AlarmManager.RTC_WAKEUP, futureDate.getTime(), sender); 

} 

現在我爲此設置了一個測試環境,每隔兩分鐘就會關閉一次,它似乎工作正常,但是當我部署到實際設備時,接收器似乎不會接收到警報。我認爲這可能是設備睡着時的問題,所以我添加了電源管理器。但它仍然不能正常工作:

 PowerManager pm = (PowerManager) context 
    .getSystemService(Context.POWER_SERVICE); 
    PowerManager.WakeLock wl = pm.newWakeLock(
    PowerManager.PARTIAL_WAKE_LOCK, "keepAlive"); 
    wl.acquire(); 
    setFutureAppointments(context.getApplicationContext()); 
    AppointmentManager.setFutureAppointmentCheck(context 
    .getApplicationContext()); 
    User.setLongSetting(context.getApplicationContext(), "futureappts", 
    new Date().getTime()); 
    wl.release(); 

任何人都看不到我做的公然錯還是我這個錯誤?感謝任何和所有的幫助。

回答

43

我通常做一些沿的線條更:

Intent i = new Intent(this, MyService.class); 
PendingIntent pi = PendingIntent.getService(this, 0, i, 0); 
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
am.cancel(pi); // cancel any existing alarms 
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
    SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY, 
    AlarmManager.INTERVAL_DAY, pi); 

這樣,您就不必擔心重新設置AlarmManagerService

我通常在我的應用程序啓動時(我的主要活動中爲onResume)以及設置爲接收BOOT_COMPLETEDBroadcastReceiver運行此位代碼。

我已經寫了一個關於創建Service s和使用AlarmManager的指南,這是基於我自己的經驗和一些技巧&我從觀看Google I/O談話中摘取的技巧。如果你有興趣,你可以閱讀它here


下面來回答你的問題,我所能做的就是報價the docs

public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation) 

計劃有不準確的觸發時間要求重複報警;例如,每小時重複一次的警報,但不一定每小時都重複一次。與由setRepeating(int,long,long,PendingIntent)提供的嚴格重現相比,這些警報功耗更高,因爲系統可以調整警報的相位以使它們同時觸發,避免超過必要的喚醒設備。

您的鬧鈴的第一個觸發將不會在請求的時間之前,但它可能在該時間之後的幾乎整個時間間隔內不會發生。另外,雖然重複報警的整個週期將按照要求進行,但報警的任何兩次連續發射之間的時間可能會有所不同。如果您的應用程序要求非常低的抖動,請改用setRepeating(int,long,long,PendingIntent)。

總之,這不是很清楚。文檔只是說警報「可能會有所不同」。但是,重要的是要知道,第一個觸發器在該時間段之後的幾乎整個時間間隔內可能不會發生。

+0

我認爲,服務可能比我更需要我在做什麼拍後報警,但你的博客是一個很好看的!你碰巧知道SetInexactRepeating通常有多少偏移量? – ninjasense 2010-12-13 17:52:32

+1

我編輯了我的答案來解釋'setInexactRepeating'問題。 – Felix 2010-12-14 10:45:40

+3

作爲獎勵,而不是在設置新的之前取消,您可以檢索PendingIntent和PendingIntent.FLAG_CANCEL_CURRENT作爲最後一個參數,它具有相同的效果。 – nsL 2013-10-18 17:12:51

4

這是工作,這將每5秒

private void setRecurringAlarm() { 

     Logger.d(IConstants.DEBUGTAG, "Setting Recurring Alarm"); 

     Calendar updateTime = Calendar.getInstance(); 

     updateTime.set(Calendar.SECOND, 5); 

     Intent alarmIntent = new Intent(this, AlarmReceiver.class); 
     PendingIntent recurringDownload = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT); 
     AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
     alarms.cancel(recurringDownload); 
     alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 1000 * 5, recurringDownload); //will run it after every 5 seconds. 
    } 
+0

setInexactRepeating和setRepeating之間的區別是什麼? – 2013-09-23 07:05:14

+0

http://developer.android.com/reference/android/app/AlarmManager.html – 2013-09-23 07:35:42

+1

安排具有不精確的觸發時間要求的重複警報;例如,每小時重複一次的警報,但不一定每小時都重複一次。與由setRepeating(int,long,long,PendingIntent)提供的嚴格重現相比,這些警報功耗更高,因爲系統可以調整警報的相位以使它們同時觸發,避免超過必要的喚醒設備。 – 2013-09-23 07:37:22