2011-08-18 71 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(); 

我没有做过这样的事个人,所以我不知道什么样的服务可以做通知用户或启动活动,但它确实有一个活动可用的全部选项,所以是的。

哦,但它只是发生在我身上,你需要使用一个处理程序,因为这里的多线程方面。