SomeGuy
SomeGuy

Reputation: 13

AlarmManager doesn't go off when set through calendar.getTimeInMillis()

public int onStartCommand(Intent intent, int flags, int startId) {

    ...

    for (int i = 1; i < dayStore.getInt("lessonCount" , 0)+1; i++) {

        String lesson = dayStore.getString("Lesson" + i , "null");
        String lessonWithoutTime = (lesson.substring(6, lesson.length()-6)).replace(".", "");

        String lessonTitleRaw = lessonWithoutTime.split(" ")[0];
        String lessonTitle = lessonTitleRaw.replace(".", "");

        String startTime = lesson.substring(0, 5);

        //---------------------------------------------------

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(startTime.substring(0,2)));
        calendar.set(Calendar.MINUTE, 0);
        calendar.add(Calendar.MINUTE, Integer.parseInt(startTime.substring(3,5))-5);

        Intent notifications = new Intent(this, StartNotification.class);

        notifications.putExtra("LessonTitle", lessonTitle);
        notifications.putExtra("StartTime", startTime);

        PendingIntent pendingNotifications = PendingIntent.getService(this, 0, notifications, 0);
        AlarmManager startNotif = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        startNotif.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingNotifications);
    }

    stopSelf();

    return super.onStartCommand(intent, flags, startId);
}

So in the code above it goes through a "for i" loop where it creates an AlarmManager for the start of each lesson. When the AlarmManager goes of it opens a service called "StartNotification" that than makes a notification like this...

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.main_icon)
            .setContentTitle(lesson)
            .setTicker(lesson + " starts in 5 minutes")
            .setContentText(lesson + " from " + startTime + " to " + endTime);

    mBuilder.setDefaults(Notification.DEFAULT_LIGHTS);
    mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);

    NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);
    mNotificationManager.notify(1, mBuilder.build());

    stopSelf();

The problem is that the AlarmManager doesnt work, or it might be a problem with the calendar. Because when I change it to this startNotif.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, pendingNotifications); (from calendar.getTimeInMillis --> System.currentTimeMillis() + 1000) It works fine, but only for the first alarm. Although you'd think all (5 in this case) alarms/notifications would go off at the same time (in 1000 mills), only the first one does.

I know that all the alarms are being set because I've used Log.D:s extensively. The calendar has the correct milliseconds, I've checked that in many different ways.

These are my permission:

<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>

And services:

    <service android:enabled="true" android:name=".Notifications" />
    <service android:enabled="true" android:name=".StartNotification" />        
    ...

Upvotes: 1

Views: 222

Answers (1)

Marat
Marat

Reputation: 6703

First of all you need to change the line where you create a PendingIntent. The problem is that you are creating first alarm with some pending intent and on the second loop (where you want to create alarm for second lesson) you are using same pending intent and so on.

When using the same pending intent for two different alarms only the last one will be set and then triggered and previous one be deleted from system.

You need different pending intents for each of the 5 lessons. In your case you need to use different requestCode as your intents are same (PendingIntent doesn't compare extras). The simple solution might be to pass integer i of your for loop.

PendingIntent pendingNotifications = PendingIntent.getService(this, i, notifications, 0);

You also need to consider how often you reset these alarms. If you think that alarms for same lessons may be set again in nearest future, then consider using flags of pending intent. The reason is to update existing pending intents or use old ones but reset time and so on. Therefore, consider that as well.

The code for calendar object seems to be fine. Just make sure (using logs) that the minutes and hour you set by getting them from string are correct. maybe you could also try code below to get your locale specific time.

Calendar calendar = Calendar.getInstance(TimeZone.getDefault());

Upvotes: 1

Related Questions