2011-08-18 56 views
0

我有一個主要活動,用戶可以在其中啓用/禁用通知,設置通知間隔以及設置通知間隔將使用的基準時間。通知通常會相互觸發約2小時。經過一段時間後,累加器將達到最大值,不再需要通知。實現通知服務的技巧

實施此類通知方案的標準方式是什麼?我嘗試在使用postAtTime的服務中使用處理程序,但似乎有很多條件可能導致它永遠不會運行。我查看了服務中的計時器,但將手機置於待機狀態將停止任何計時器,再加上它似乎是一個不好的主意。

我遇到的唯一的其他選項我尚未探索,但它涉及使用AlarmManagerBroadcastReceiver。我應該拋棄服務並安排重複報警嗎?一旦我的累加器達到最大值,我需要能夠禁用所有剩餘的警報。

感謝您的任何意見。

回答

0

由於我將始終有有限數量的通知,並且我可以提前計算已用時間,所以看起來AlarmManagerBroadcastReceiver的組合工作得很好。這裏是我是如何實現這一點:

我首先創建一個BroadcastReceiver

public class NotificationReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 

     //Get handle to system notification manager 
     NotificationManager mNM = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); 

     //Get message from intent 
     Bundle bundle = intent.getExtras(); 
     CharSequence text = bundle.getString("notification_message"); 

     // Set the icon, scrolling text and timestamp 
     Notification notification = new Notification(R.drawable.notification_icon, text, System.currentTimeMillis()); 

     // The PendingIntent to launch our activity if the user selects this notification 
     PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); 

     // Set the info for the views that show in the notification panel. 
     notification.setLatestEventInfo(context, context.getText(R.string.app_name),text, contentIntent); 

     // Set Flags 
     notification.flags |= Notification.FLAG_AUTO_CANCEL; 

     // Send the notification. 
     mNM.notify(R.string.notification, notification); 

    } 

} 

然後,我創建了一個使用AlarmManager創建一個類/取消發送消息給BroadcastReceiver

public class NotificationSender { 

    private AlarmManager mAlarmManager; 
    private Context mContext; 
    private Intent mIntent; 

    public NotificationSender(Context context){ 

     this.mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     this.mIntent = new Intent(context, NotificationReceiver.class); 
     this.mContext = context; 
    } 

    public void setAlarm(Long etaMillis, int accumulator){ 

     //Create intent to send to Receiver 
     this.mIntent.putExtra("notification_message","Message"); 

     //Use accumulator as requestCode so we can cancel later 
     PendingIntent sender = PendingIntent.getBroadcast(this.mContext, accumulator, this.mIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

     //Set Alarm 
     mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, etaMillis, sender); 

    } 

    public void cancelAlarms(){ 

     //requestCode (accumulator) will always be a multiple of 10 and less than 100 
     for (int x = 10; x <= 100; x += 10){ 
      PendingIntent operation = PendingIntent.getBroadcast(this.mContext, x, this.mIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
      mAlarmManager.cancel(operation); 
     } 

    } 

    public void createAlarms(PreferenceHelper prefs){ 

     //Calculate time notifications are due and set an alarm for each one 
     //PreferenceHelper is a class to help pull values from shared preferences 
     Date currentTime = new Date(); 

     for (int i = prefs.getNotificationInterval(); i <= 100; i += prefs.getNotificationInterval()) { 

      if (i > prefs.getAccumulator()) { 

       this.setAlarm(SystemClock.elapsedRealtime() + calculateETA(i, prefs).getTime() - currentTime.getTime(), i); 

      } 

     } 

    } 

    public void refreshAlarms(PreferenceHelper prefs){ 

     this.cancelAlarms(); 
     if (prefs.isNotificationsEnabled()) this.createAlarms(prefs); 

    } 

} 
報警

重要的部分是使用累加器作爲requestCode,因此我們可以稍後取消所有的報警。

最後我在onCreate()調用refreshAlarms()並且每當用戶修改是相關的調度通知偏好使用的NotificationSender類在我的活動。重新啓動手機將清除所有鬧鐘,以便在通知開始前必須重新啓動應用程序。如果系統碰巧殺死了進程,報警仍然會在適當的時候觸發。

+0

即使我殺了應用程序,它仍會運行嗎? –

0

如果你開始的滋生這樣一個線程服務:

thread t = new thread(new Runnable(){ 
    public void Run(){ 
     boolean notified = false; 
     while(!notified){ 
      if(notify_time - time > 1000){ 
       Thread.sleep(999); 
      else if(notify_time - time <= 0){ 
       // START NOTIFICATION ACTIVITY 
       notified = true; 
      } 
     } 
    } 
} 

t.start(); 

我沒有做過這樣的事個人,所以我不知道什麼樣的服務可以做通知用戶或啓動活動,但它確實有一個活動可用的全部選項,所以是的。

哦,但它只是發生在我身上,你需要使用一個處理程序,因爲這裏的多線程方面。