Search code examples
javaandroidalgorithmnotificationsalarmmanager

Notification AlarmManager Problems


I have three questions:

1) I have implemented this so far:

public final class CalculateTime {

    public int iHour;
    public int iMinute;
    public Calendar calendar;

    private void calculateRandomNumbers() {
        Random randomNumberGenerator = new Random();
        iHour = randomNumberGenerator.nextInt(19 - 9) + 9;
        iMinute = randomNumberGenerator.nextInt(59);
    }

    public void calculateRandomTime() {
        calculateRandomNumbers();
        calendar = GregorianCalendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, iHour);
        calendar.set(Calendar.MINUTE, iMinute);
    }
}

So the notification should push once anytime between 9 and 19 o'clock. But the notification is sent twice between 9 and 19 o'clock.

2) When the calculation is in the past, the notification is pushed right away.

3) I want to send a notification once a week, how do I Implement this? I have tried:

// For Monday
calendar.set(Calendar.DAY_OF_WEEK, 2)

But I am not sure if this is right, because I can't test this easily. (I cannot wait a week everytime!) :/

Some more Code, to set the alarm:

public final class NotificationService extends IntentService {

    public static final String DESCRIPTION = "description";
    public static final String HEADLINE = "headline";

    private static final int FM_NOTIFICATION_ID = 0;

    public NotificationService() {
        super("NotificationService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        /*
         * This method is invoked whenever an intent for this service is fired.
         * The actual firing is done by the AlarmManager in the
         * TodoEntriesAdapter, but really we don't care at this point where
         * exactly the intent came from.
         */
        String description = intent.getStringExtra(DESCRIPTION);
        String headline = intent.getStringExtra(HEADLINE);

        addNotification(description, headline);
    }

    private void addNotification(String description, String headline) {

        NotificationCompat.Builder builder =
            new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(headline)
            .setContentText(description)
            .setAutoCancel(true);

        Intent notificationIntent = new Intent(this, ReadNotification.class);
        notificationIntent.putExtra("description", description);
        notificationIntent.putExtra("headline", headline);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,   
            PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(contentIntent);

        // Add as notification  
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
        manager.notify(FM_NOTIFICATION_ID, builder.build());  
        }
    }

Solution

    1. The notification is sent twice.

      Seeing the code that actually interacts with the AlarmManager would be helpful. If you display the selected time (using for example the logging facility) you will be able to see which notification is the right one and if the code that schedules the alarm is being called twice.

    2. When the calculation is in the past, the notification is pushed right away.

      This is the documented behaviour. You will need to manually check if the time is in the past, and move it forward by a week if it is.

    3. I want to send a notification once a week.

      Try setRepeating(type, start, 7 * AlarmManager.INTERVAL_DAY, operation).

      I can't test this easily.

      Besides the primitive method of changing the phone's date manually, you can test the app by mocking the AlarmManager class (replace it with a dummy class that checks the right methods are called with the right parameters).