PopUp Alarm on selected days and selected time in android - android

I want to popup an alarm on selected day i.e. Monday ,Tuesday and so on. And at selected time on every week. I've an idea about interval but I don't know how to get the next day and popup alarm ?

You need to use the AlarmManager and get a WakeClock while processing the Intent in Service (make sure to release it and chose the right kind).
Here is a great example :
https://stackoverflow.com/a/8801990/220710
To get the day current day of the week, look at this question :
Android: how to get the current day of the week (Monday, etc...) in the user's language?
Then you would use :
setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
Schedule a repeating alarm
that has inexact trigger time requirements; for example, an alarm that
repeats every hour, but not necessarily at the top of every hour.
Then you would need to set :
type = RTC_WAKEUP
intervalMillis = ms in a week
triggerAtMillis = System.currentTimeMillis() + ms to the next Monday, Tuesday or
whatever
intent = the intent you want to fire to a Service that
will process it.

Related

Android AlarmManager scheduling through time zone or daylight shifts

I have a logic that schedules reminders using AlarmManager. I need to implement the following:
Logic 1: when the user changes time zone, eg he travels from UK (UTC+0) to central Europe (UTC+1), alarms should follow the time zone.
Example, a reminder scheduled at 3PM UTC+0 should fire at 4PM UTC+1
Logic 2: when a time shift occurs, eg time shifts to daylight saving time in spring (from UTC+1 to UTC+2), alarms should keep the original time
Example, a reminder scheduled at 3PM UTC+1 should fire at 3PM UTC+2
How can I achieve this? As of now I have no particular logic in place and all the alarms follow Logic 1. I have found no way to identify when a time shift happens.
Scheduling logic is very simple:
LocalDateTime reminderTime = LocalDateTime.of(...)
ZoneOffset currentOffsetForMyZone = ZoneId.systemDefault().getRules().getOffset(Instant.now());
reminderTime.toInstant(currentOffsetForMyZone).toEpochMilli();
alarmManager.setExact(AlarmManager.RTC_WAKEUP, reminderTime, pendingIntent);
For each alarm store the time of day and the time zone in which it was set. This suffices for firing the alarm at the right time no matter if the user is currently in a different time zone. And Java will take summer time (DST) into account.
Your example times and UTC offsets correspond to standard time in those time zones, so let’s start with an example date in standard time even though it was a couple of days ago now:
LocalTime alarmTime = LocalTime.of(15, 0);
ZoneId alarmTimeZone = ZoneId.of("Europe/London");
// Travel to Paris and see the alarm go off at 4, assuming standard time
ZoneId currentTimeZone = ZoneId.of("Europe/Paris");
Instant actualAlarmTime = LocalDate.of(2021, Month.MARCH, 18)
.atTime(alarmTime)
.atZone(alarmTimeZone)
.toInstant();
ZonedDateTime timeOnLocation = actualAlarmTime.atZone(currentTimeZone);
System.out.format("Scheduled at %s or %d millis, goes off at %s local time%n",
actualAlarmTime, actualAlarmTime.toEpochMilli(), timeOnLocation);
The code prints:
Scheduled at 2021-03-18T15:00:00Z or 1616079600000 millis, goes off at
2021-03-18T16:00+01:00[Europe/Paris] local time
Let’s also try a date in the summer time part of the year. I have changed Paris to London and MARCH to APRIL:
// Stay back home in the UK
ZoneId currentTimeZone = ZoneId.of("Europe/London");
Instant actualAlarmTime = LocalDate.of(2021, Month.APRIL, 18)
.atTime(alarmTime)
.atZone(alarmTimeZone)
.toInstant();
Scheduled at 2021-04-18T14:00:00Z or 1618754400000 millis, goes off at
2021-04-18T15:00+01:00[Europe/London] local time
The basic trick is: don’t use the current offset for the time zone where you set the alarm. Let Java automatically apply the offset for the date and time where the alarm is to go off.
If anyone is interested, the fix was to apply the correct offset for the date and time where the alarm is to go of, as pointed out by Ole. My silly mistake was to apply always the current timezone.
LocalDateTime alarmTime = LocalDateTime.of(...)
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime zoneDateTime = ZonedDateTime.of(alarmTime , zone);
long startAtMillis = zoneDateTime.toInstant().toEpochMilli();
//Fire alarm
notificationAlarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, startAtMillis, pendingIntent);

How to send a notification on specific dates by checking the date

I have an application which I want to send notifications in odd days (like 1,3,5 days of month). After research, I understood that I need a service. But I can't figure out how to get the new date every day, or how to notice the service that the day has changed... Something like a listener on day changed... I searched a lot, and only found references on how to schedule a notification at a certain date, but that's not what I need, as I want to verify date every day. Thank you very much for any help !
You can do this with the help of Android Alarms.
The steps that you need to do :
Start an Alarm for the date and time at which you need to show the notification.
Subscribe for Reboot Broadcast receiver and set the same alarm again (since the alarm that you set will be gone once the device is restarted)
Once the alarm is ticked, you can show the notification from the Alarm Broadcast receiver and then set for the new alarm.
To schedule an ALarm :
AlarmManager mgr=
(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(ctxt, ScheduledService.class);
PendingIntent pi=PendingIntent.getService(ctxt, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + DIFF_PERIOD, PERIOD, pi);
Where PERIOD : 48hours in millisecond
DIFF_PERIOD : time to your nearest tick. That is if you are in day 2 and you need to trigger the alarm in day 3, then this value will be : 24hrs in millisecond
To answer your comment.
To find the day of the month, you can use the follwing :
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);

Figure out the time in millis for alarm

I am making a simple alarm clock application that mimics the default alarm app that comes with Android Lollipop.
The set*( ) methods of an AlarmManager require the date on which the alarm should be fired as a Unix epoch.
The UI is rather simple with a TimePicker.
So, given the current time and the time the user has selected from TimePicker, how do I figure out the time in milliseconds when the alarm should be fired?
Update:
There are two cases I run into:
Selecting the time that is after the current time:
Assume it is 11am and the user selects the time from the time picker as 03pm. In this case, I know that the alarm should be scheduled for the same day.
Selecting the time that is before the current time:
Assume it is 11am and the user selects the time from the time picker as 10am. In this case, I know that the alarm should be scheduled for the next day's 10am.
Ok here you go:
// Get the current time
final Date currentTime = new Date();
// Set the hours and minutes from the time picker against todays date
final Calendar selectedTime = Calendar.getInstance();
selectedTime.set(Calendar.HOUR_OF_DAY, hourFromTimePicker);
selectedTime.set(Calendar.MINUTE, minuteFromTimePicker);
// If the current date is greater than the hour and minute from time picker add one day
if (currentTime.getTime() > selectedTime.getTime().getTime()) {
selectedTime.add(Calendar.DAY_OF_YEAR, 1);
}
// Schedule the alarm
//AlarmManager.set(selectedTime.getTime().getTime());
if you store data in java Date object:
long getTime( )
Returns the number of milliseconds that have elapsed since January 1, 1970.just subtract.
Another way if you look only at time within day:
int ms = 1000*SECONDS + 1000*60*MINUTES + 1000*60*60*HOURS
I would use a android.text.format.Time class
call the setters on the Time class to set the Hour, Minute, Second, etc. The Hours are in 24H time, so if the current hour > selected hour then you know to increment days by 1
Finally, call Time#toMillis(boolean ignoreDst) to get the system time in millis, and pass that to AlarmManager
EDIT: GregorianCalendar should be used instead.

android best way to set an alarm in android

i have a general question to set an alarm in android.
at the moment, the user can chose a date and time with a date picker (which is a date in the future).
then i will set the the delay time for the alarm.
I convert the chosen date & time in milliseconds and subtract System.currentTimeMillis() = this difference I set for the delay of my alarm.
my question is, if this the best way to calculate the delay or is there a better solution?
this calculation i use for update an alarm, too
Look at the Android Alarm Manager class. You can use it to set alarms at specific times, without calculating the delay.
final AlarmManager am = (AlarmManager) App.instance.getSystemService(Context.ALARM_SERVICE);
Calendar c = GregorianCalendar.getInstance();
c.set(2015, 12, 20, 10, 30);
am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), operation);
where operation is a PendingIntent of the action you want to do when the alarm triggers.
My solution for you here:
You should convert normal datetime to timestemp formart
You can calculate by subtract future timestemp (which is set by alarm time) with current timestemp of phone to get return value then convert it to hour, munite and day number.
If after calculate get result is zezo then you notify alarm to user.
else nothing to do

Setting android alarm manager on certain days

I'm building an app that uses alarm manager. The user sets day and time and there is 7 checkboxs, one for each day of the week and the ones they tick the alarm will go off on them days. Like i know you can put date and time into the alarm manager is there any way i can put like day and time into alarm manager and them it will go off on that day every week?
AlarmManager.setRepeating takes as parameter:
type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP}, RTC or RTC_WAKEUP.
Here you will want RTC or RTC_WAKEUP
triggerAtTime Time the alarm should first go off, using the appropriate clock (depending on the alarm type).
Here you give the date/time of the first alarm (I believe this must be UTC time, so be careful)
Calendar calendar = new GregorianCalendar(2011, Calendar.APRIL, 19, 23, 12);
long firstTime = calendar.getTimeInMillis();
interval Interval between subsequent repeats of the alarm.
To repeat every week, you will give as interval the number of milliseconds in a whole week:
long interval = 1000 * 60 * 60 * 24 * 7;
or
long interval = 7 * AlarmManager.INTERVAL_DAY;

Categories

Resources