How to cancel PendingIntent at specific time? - java

AlarmManager works perfectly when I have not declared cancel but do not fire when I declare the cancel..
Here is the code:
Calendar c= Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 37);
c.set(Calendar.SECOND, 0);
Toast.makeText(this, c.getTime().toString(), Toast.LENGTH_LONG).show();
intent = new Intent(TestAlarm.this, TestAlarmService.class);
pi = PendingIntent.getService(TestAlarm.this, 1, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);
and cancel code:
c.add(Calendar.HOUR_OF_DAY, 0);
c.add(Calendar.MINUTE, 38);
c.add(Calendar.SECOND, 0);
PendingIntent pi1=PendingIntent.getService(TestAlarm.this, 1, intent, 0);
AlarmManager am1 = (AlarmManager) getSystemService(ALARM_SERVICE);
//stopService(intent);
am1.cancel(pi);
Now here I want to start my AlarmManager to go off at 12:37 and cancel after one or two minutes...But Whenever I use cancel code the AlarmManager never fires...
Thanks in Advance! :)

Change the line am1.cancel(pi); to am1.cancel(pi1); - you're cancelling the original PendingIntent
Also, in your cancel code, you're calling c.add() (which add on to the current date/time) instead of c.set() (which explicitly sets the next date/time). By calling c.add(Calendar.MINUTE, 38), you're actually adding 38 minutes to the current Calendar, instead of setting the time to 12:38;

Related

Android Studio daily notification API 31+

I am attempting to set daily notifications in my app, but they only seem to be working one time. Additionally, I am attempting to make it work also on API 31 and higher.
int hourOfDay = timePicker.getHour();
int minute = timePicker.getMinute();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
if(calendar.getTimeInMillis() < System.currentTimeMillis())
calendar.add(Calendar.DATE, 1);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(TimerPickerAct.this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(TimerPickerAct.this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
I tried to do it this way but in this way I don't get any notification.
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pendingIntent)

How to delay android repeating notification start

I am using this code to start notification that will repeat every 3 days:
public void setNotification() {
boolean alarmUp = (PendingIntent.getBroadcast(this, 10000,
new Intent(this, NotificationReceiver.class),
PendingIntent.FLAG_NO_CREATE) != null);
if (!alarmUp) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 21);
Intent myIntent = new Intent(this, NotificationReceiver.class);
int ALARM1_ID = 10000;
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, ALARM1_ID, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
assert alarmManager != null;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() + AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY * 3, pendingIntent);
}
}
Everything looks good but I want my notification to start 1 day after first starting the application and calling this function. I thought that calendar.getTimeInMillis() + AlarmManager.INTERVAL_DAY part in:
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() + AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY * 3, pendingIntent);
is responsible for the first start. But it looks like it is not. Even though I set it to start after 1 day, notification shows up to user immediately after calling this function.
Help?
Use setInexactRepeating() instead of setRepeating(). When you use setInexactRepeating(), Android synchronizes repeating alarms from multiple apps and fires them at the same time.
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
AlarmManager.INTERVAL_DAY * 3, pendingIntent);
Note that:
ELAPSED_REALTIME: Fires the pending intent based on the amount of time since the device was booted, but doesn't wake up the device. The elapsed time includes any time during which the device was asleep.
RTC_WAKEUP: Wakes up the device to fire the pending intent at the specified time.

Android Notification triggering on application startup

I'm trying to get my Daily Notification Service working properly but I am stuck with an issue.
I should receive a notification only at a specific time of the day in the future but I noticed that
if (time_that_i_set_for_notification < current_time_of_the_day) notification triggers at the boot of my app
That's wrong because in that condition, the notification should trigger only the next day, not in the instant I launch the app.
Here's my attempt to get the things working:
I call this in my MainActivity, onCreate() method:
private void scheduleNotification(int hour, int minute){
Intent notificationIntent = new Intent(this, NotificationReceiver.class);
notificationIntent.putExtra("notifId", notifId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notifId, notificationIntent, 0);
// Set the alarm to start at approximately at a time
DatePicker datePicker = new DatePicker(this);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
if(calendar.getTime().compareTo(new Date()) < 0) calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 12);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
I thought that adding if(calendar.getTime().compareTo(new Date()) < 0) calendar.add(Calendar.DAY_OF_MONTH, 1); I would've achieved the result I needed.
Thank you and have a nice day.
Before calling setInexactRepeating, add this check:
if (calendar.getTimeInMillis() < System.currentTimeMillis())
calendar.setTimeInMillis(calendar.getTimeInMillis() + AlarmManager.INTERVAL_DAY);
Hope this helps.
Ok there's a wrong check there, if you change it, you should be able to solve your issue.
Here we go:
Intent notificationIntent = new Intent(this, NotificationReceiver.class);
notificationIntent.putExtra("notifId", notifId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notifId, notificationIntent, 0);
// Set the alarm to start at approximately at a time
DatePicker datePicker = new DatePicker(this);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
//if(calendar.getTime().compareTo(new Date()) < 0) calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 50);
if (calendar.getTimeInMillis() < System.currentTimeMillis()) calendar.setTimeInMillis(calendar.getTimeInMillis() + AlarmManager.INTERVAL_DAY);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
I commented //if(calendar.getTime().compareTo(new Date()) < 0) calendar.add(Calendar.DAY_OF_MONTH, 1);
because it should be unnecessary.
Let me know if it worked.
UPDATE: You should totally check whether the Service that handles your daily notification is high consume or not. A High-draining battery app would bother your users.

AlarmManager going off whenever app opens

I am trying to set an AlarmManager to go off for a specific time during the day. Here is my current code on it -
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 16);
calendar.set(Calendar.SECOND, 0);
long time = calendar.getTimeInMillis();
Intent intent = new Intent(MainActivity.this, Drawing.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, time,
AlarmManager.INTERVAL_DAY, pendingIntent);
The drawing class displays a notification. The alarm does go off at the right time, but anytime the app is re-opened the notification goes off immediately.
I know its nothing to do with the drawing class because when i set the alarm to just go off with System.currentTimeInMillis() + 10 secs it works fine, even when app is reopening.
Any ideas? What is wrong with my logic?
You are not checking to see if calendar is in the past, as it will be ~2/3rds of the time (i.e., any time this code is run after 08:16). You will need to add() a day in that case, to get 8:16 for tomorrow.

Android alarm manager

Hi i've been researching the alarm manager in android and was wondering if there how to set a specific time for an alarm (or could use notification manager)to go off at a specific time for example 12pm tomorrow .
The code below sets the alarm for 5 seconds from now so to set it for something like 12 pm could you do something like 12:00:00 or something?
Intent intent = new Intent(this, OnetimeAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (5 * 1000), sender);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
Java's Date and Time libraries are a huge hassle, but this should give you an idea:
// the time now
Calendar calendar = Calendar.newInstance();
// noon tomorrow
calendar.add(Calendar.DAY_OF_YEAR, 1);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
Calendar calendar = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
this should work

Categories