How to set Alarm for working days in android
Asked Answered
L

4

6

I have a scenario

Setting alarm for (Monday to Friday)

Let say I choose time that is: hour = 9, minutes = 15, am_pm = "AM".

Now I want to set Alarm for every Monday to Friday at 9:15 AM

Code below I tried but not getting desired result.

if(choice.equals("Week Days (Mon-Fri)"))
{
    for(int a = 2; a <= 5; a++) //here I am assuming a is from 2 to 5 (calendar DAY_OF_WEEK from Monday to Friday)
    {
        Calendar alarmCalendar = Calendar.getInstance();

        alarmCalendar.set(Calendar.HOUR_OF_DAY, _hourOfDay);

        alarmCalendar.set(Calendar.MINUTE, _minute);

        alarmCalendar.set(Calendar.SECOND, 0);

        alarmCalendar.set(Calendar.MILLISECOND, 0);

        if(am_pm.equals("AM"))
        {
            alarmCalendar.set(Calendar.AM_PM, 0);
        }
        else
        {
            alarmCalendar.set(Calendar.AM_PM, 1);
        }


        alarmCalendar.set(Calendar.DAY_OF_WEEK, a);

        Long alarmTime = alarmCalendar.getTimeInMillis();

        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
                alarmTime, 24 * 60 * 60 * 1000 , pendingIntent);
    }

    Toast.makeText(ActivityReminder.this, "Meeting Reminder Set on Week Days (Mon-Fri)", 
                        Toast.LENGTH_LONG).show();
}

I've used BroadcastReceiver like:

public class AlarmReceiver extends BroadcastReceiver
{
    NotificationManager mNotificationManager;

    Context context;

    public static final String TAG = "Reminder...";

    @Override
    public void onReceive(Context context, Intent intent)
    {
        this.context = context;

        String subject = "<h3>Meeting Reminder: </h3>" + intent.getStringExtra("subject");

        Toast.makeText(context, Html.fromHtml(subject), Toast.LENGTH_LONG).show();

        showNotification(subject);
    }

    @SuppressWarnings("deprecation")
    private void showNotification(String msg) 
    {
        Intent notificationIntent = new Intent(context.getApplicationContext(),
                ActivityMainScreen.class);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);

        stackBuilder.addParentStack(ActivityMainGeofence.class);

        stackBuilder.addNextIntent(notificationIntent);

        String arrivalTime = TimeUtil.toString(Calendar.getInstance().getTime(), 
                "dd-MM-yyyy hh:mm:ss a");

        notificationIntent.putExtra("subject", msg)
        .putExtra("time", arrivalTime).putExtra("type", "Meetings/Reminder");

        PendingIntent notificationPendingIntent = stackBuilder
                .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

        Notification notification = new Notification();
        notification.icon = R.drawable.app_icon;

        notification.setLatestEventInfo(context.getApplicationContext(), 
                "WFM Meeting Reminder", Html.fromHtml(msg), notificationPendingIntent);

        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        notification.defaults |= Notification.DEFAULT_SOUND;

        notification.defaults |= Notification.DEFAULT_VIBRATE;

        NotificationManager mNotificationManager = (NotificationManager) 
                context.getSystemService(Context.NOTIFICATION_SERVICE);

        mNotificationManager.notify(0, notification);

    }
}

Finally in Manifest:

<receiver android:name="com.my_package_name.AlarmReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
</receiver>

EDITED: Here I want to tell that One Time Alarm worked for me but for above choice Week Days (Mon-Fri) is not working correctly

The working code is:

if(choice.equals("One Time"))
{
    alarmManager.set(AlarmManager.RTC_WAKEUP, PERIOD, pendingIntent); // here PERIOD is the time selected by me in milliseconds...

    Toast.makeText(ActivityReminder.this, "Meeting Reminder Set One Time", 
            Toast.LENGTH_LONG).show();
}

Where am I doing wrong. Any help would be appreciated.

Larghetto answered 11/11, 2014 at 7:46 Comment(0)
S
5

I would assume that the alarm only gets set for Friday at 9:15? This should be because of the following line in the AlarmManager docs:

If there is already an alarm scheduled for the same IntentSender, it will first be canceled. http://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent)

In order to do what you want, you'd either want 5 PendingIntents or just set an alarm for the first event, and when that alarm is received, you set the alarm for the next day and so on.

I'd probably go with the second option, since in the first method you'd need 5 different PendingIntents, which means that their requestCode or backing Intent must be different (with different type, action, or category).

Sarette answered 21/11, 2014 at 20:6 Comment(0)
L
3

Try this code its worked for me...

    for (int k = 2; k < 5; k++) {
                    int sday = k;
                    Calendar today = Calendar.getInstance();
                    Calendar AlarmDate = Calendar.getInstance();
                    AlarmDate.set(Calendar.HOUR_OF_DAY, inputH);
                    AlarmDate.set(Calendar.MINUTE, inputM);
                    AlarmDate.set(Calendar.SECOND, 0);
                    while (today.after(AlarmDate)) {
                        AlarmDate.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    while (AlarmDate.get(Calendar.DAY_OF_WEEK) != sday) {
                        AlarmDate.add(Calendar.DAY_OF_MONTH, 1);
                    }

                    Intent i = new Intent(this, AlertPopUpActivity.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                    i.putExtra("uid", k + (alert.getId() * 1000)); //a unique id for alram
                    i.putExtra("id", alert.getId());
                    i.putExtra("msg", alert.getEventName());

                    if (minute < 10)
                        i.putExtra("time", hour + ":0" + minute);
                    else
                        i.putExtra("time", hour + ":" + minute);
                    i.putExtra("ampm", inputAMPM);
                    PendingIntent pi = PendingIntent.getActivity(this,
                            k + (alert.getId() * 1000), i,         //same unique id (used to update alram if canceled)
                            PendingIntent.FLAG_UPDATE_CURRENT);

                    am.set(AlarmManager.RTC_WAKEUP, AlarmDate.getTimeInMillis(), pi);
                    System.out.println("Set Time :" + AlarmDate.getTime());
                }
Lovelace answered 23/11, 2014 at 18:54 Comment(0)
C
2

Check out the page for AlarmManager, and look at the note in setRepeating(). As of API 19, the repeating functions are inexact. To get the proper repetition you have to handle the alarm each time and reschedule it.

Concourse answered 11/11, 2014 at 18:27 Comment(0)
U
2

) First of all you can not have for loop for same pending intent, it will cancel the previous instances.

) Solution is to set alarm again through broadcast receiver inside onReceive method, after completion of alarm.

) Here is an idea of how to achieve this, include rest of the code as per your requirement. I have used calendar class to set alarm, and on friday skip 2 days in between.

void setAlarm() {
    AlarmManager alarmManager = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
    if (choice.equals("One Time")) {
        alarmManager.set(AlarmManager.RTC_WAKEUP, PERIOD, pendingIntent);

        Toast.makeText(context, "Meeting Reminder Set One Time",
                Toast.LENGTH_LONG).show();
    } else if (choice.equals("Week Days (Mon-Fri)")) {
        Calendar calendar = Calendar.getInstance();
        int day = calendar.get(Calendar.DAY_OF_WEEK);

        switch (day) {
        case Calendar.MONDAY:
            alarmManager
                    .set(AlarmManager.RTC_WAKEUP, PERIOD, pendingIntent);
        case Calendar.TUESDAY:
            alarmManager
                    .set(AlarmManager.RTC_WAKEUP, PERIOD, pendingIntent);
        case Calendar.WEDNESDAY:
            alarmManager
                    .set(AlarmManager.RTC_WAKEUP, PERIOD, pendingIntent);
        case Calendar.THURSDAY:
            alarmManager
                    .set(AlarmManager.RTC_WAKEUP, PERIOD, pendingIntent);
        case Calendar.FRIDAY:
            alarmManager.set(AlarmManager.RTC_WAKEUP, PERIOD * 3,
                    pendingIntent);
        }
    }
}

) For "choice" in if-else condition you might have to store these value somewhere like SharedPreferences.

Ulick answered 24/11, 2014 at 4:35 Comment(2)
Suppose today is Monday. If I follow your code then in Switch-Case Calendar.MONDAY will be true and alarmManager will set it on monday...Fine but what about if next day on TUESDAY. If I won't run the app then how alarm will be passed through Calendar.TUESDAY ??Larghetto
I think you didn't get my second point, you need to set alarm again inside broadcast receiver class, when you are calling showNotification(subject); inside onReceive method. You don't have to run the app AlarmManager will do it for you.Ulick

© 2022 - 2024 — McMap. All rights reserved.