пятница, 19 августа 2011 г.

Android: AlarmManager and notification example





Let's talk about a task, that many application developers have to complete: notification user at time, specified by user, without using timer and service.

I suppose, that we already have got property "notifyTime" as a string value, (looks like "14:05"). I'll describe few steps, that we need to notify user everyday at specified time.

1. We need custom BroadcastReceiver class:
  
public class TimeNotification extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    // Talk about it later
    }
}
  
2. In main activity, let's realise following method:
  
 private void restartNotify() {
        // Alarm manager - magic thing that does what we need
        am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        // Intent for our  BroadcastReceiver 
        Intent intent = new Intent(this, TimeNotification.class);
        // PendingIntent for AlarmManager 
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
                intent, PendingIntent.FLAG_CANCEL_CURRENT );
        // Just in case we have already set up AlarmManager,
        // we do cancel.
        am.cancel(pendingIntent);

        //Some simple code to define time of notification:
        Calendar cal = Calendar.getInstance();
        Date stamp =  cal.getTime();
        int pos = notifyTime.indexOf(":");
        int hour = Integer.parseInt(notifyTime.substring(0, pos));
        int minute = Integer.parseInt(notifyTime.substring(pos+1));
        stamp.setHours(hour);
        stamp.setMinutes(minute);
        stamp.setSeconds(0);

        // In case it's too late notify user today
        if(stamp.getTime() < System.currentTimeMillis())
            stamp.setTime(stamp.getTime() + AlarmManager.INTERVAL_DAY);
                
        // Set one-time alarm
        am.set(AlarmManager.RTC_WAKEUP, stamp.getTime(), pendingIntent);
    }
  
Call this method in onStart() of main activity.
There is one not obvious thing: we could use am.setRepeat method with AlarmManager.INTERVAL_DAY interval. But user can change noification time preference anytime, so I decided to re-start alarm manager each time in BroadcastReceiver object. It is described in next step.

3. Fill onReceive method in TimeNotification
  
public void onReceive(Context context, Intent intent) {
        // Notification manager - we already know how to use it
        nm = (NotificationManager)        context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(R.drawable.icon, "Test", System.currentTimeMillis());
        // This is intent, we want to launch when user clicks on the notification.
        Intent intentTL = new Intent(context, MainActivity.class);
        notification.setLatestEventInfo(context, "Test", "Do something!",
                PendingIntent.getActivity(context, 0, intentTL,
                PendingIntent.FLAG_CANCEL_CURRENT));
        notification.flags = Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL;
        nm.notify(1, notification);
// Here we set next notification, in day interval
 AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
                intent, PendingIntent.FLAG_CANCEL_CURRENT);
        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + AlarmManager.INTERVAL_DAY, pendingIntent);
    }
  

4. Don't forget the main thing - add receiver to manifest file
  
    <receiver android:name=".TimeNotification" />
  

I hope that was useful!

Комментариев нет: