Android AlarmManager not cancelling alarms correctly - java

I'm working on an app which will allow users to set multiple notifications, and cancel any notification they choose.
The problem I have is that when I cancel a pending intent using the AlarmManager it is cancelling all alarms. Each of my pending intents has it's own unique request code.
For instance I would call this to create the alarm and then delete:
setAlarm(5062, 1453269670) // Set alarm 1
setAlarm(5063, 1453774418) // Set alarm 2
cancelAlarm(5062) // Cancel alarm 1
cancelAlarm(5063) // Cancel alarm 2
Setting mutiple alarms always works, I can set as many as I like and they all produce the notification. However if I was to cancel alarm 1, it also cancels alarm 2.
I know that the pending intent has to be the same when setting and cancelling, and each pending intent has it's own unique request code, so I don't know why it's not working. I've spent many hours googling, but none of the suggested answers have helped me.
void setAlarm(int request_code, long alarm_time) {
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra("request_code", request_code);
PendingIntent pendingIntent = PendingIntent.getService(context, request_code, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarm_time, pendingIntent);
}
void cancelAlarm(int request_code) {
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra("request_code", request_code);
PendingIntent pendingIntent = PendingIntent.getService(context, request_code, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
pendingIntent.cancel();
alarmManager.cancel(pendingIntent);
}

The answer is simple
Intent firstIntent = new Intent(this, Receiver.class);
intent.setAction("action 1");
intent.putExtra("extra", "extra1");
firstPendingIntent = PendingIntent.getBroadcast(this, 0, firstIntent, 0);
Intent secondIntent = new Intent(this, Receiver.class);
intent.setAction("action 2");
intent.putExtra("extra", "extra2");
secondPendingIntent = PendingIntent.getBroadcast(this, 0, secondIntent, 0);
if you compare two PendingIntents created in ABOVE code they are NOT EQUAL
But in code BELOW:
Intent firstIntent = new Intent(this, Receiver.class);
intent.setAction("action 1");
intent.putExtra("extra", "extra1");
firstPendingIntent = PendingIntent.getBroadcast(this, 0, firstIntent, 0);
Intent secondIntent = new Intent(this, Receiver.class);
intent.setAction("action 1");
intent.putExtra("extra", "extra2");
secondPendingIntent = PendingIntent.getBroadcast(this, 0, secondIntent, 0);
if you compare two PendingIntents they gonna be EQUAL, so doesn't matter what you pass in putExtra method

Related

adding a alarm cancel button in the notification

I have been working on setting alarms using AlarmManager.
Set:
Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), reqCode, myIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, now.getTimeInMillis(), pendingIntent);
cancel:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), reqCode, myIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent);
in my alarm receiver I want to be able to receive a notification which has a button that allows me to call cancelAlarm(). however I don't see the best approach to this and looking for the best and most reliable way of doing this.
I get the requestCodes so I am able tell which alarm to cancel

Android Multiple notifications BroadcastReceiver

I am trying to implement multiple notifications for each reminder I have in my app. I found some leads around here that it could be achieved using unique id per each notification but it is not working I get only one notification which is overwritten by the last one set. Also I would like know how is it possible to keep the notification intact after device is rebooted please. Here is my code
//call notification activation Intent
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
AlarmReceiver class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//creating unique id for each specific notification
int ID = (int) ((new Date().getTime()/1000L) % Integer.MAX_VALUE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notification = new Intent(context,MainActivity.class);
notification.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pi = PendingIntent.getActivity(context,0,notification,0);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mynotification = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_date_range_black_48dp)
.setContentTitle("note taker")
.setContentText("you have a reminder about a note")
.setAutoCancel(true)
.setContentIntent(pi)
.setSound(defaultSoundUri)
.setVibrate(new long[]{1000,1000,1000,1000,1000});
notificationManager.notify(ID,mynotification.build());
}
}
I found some leads around here that it could be achieved using unique id per each notification but it is not working i get only one notification which is overwritten by the last one set
I think the problem lies not in your notification, but in your AlarmManager.
Try using different ID for each PendingIntent, and set the flag to PendingIntent.FLAG_ONE_SHOT.
Your calling intent should look like this:
//call notification activation Intent
Intent intent = new Intent(getBaseContext(), AlarmReciever.class);
int RQS_1 = (int) System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Try to give different request code and PendingIntent.FLAG_UPDATE_CURRENT as Flag for Pending Intent and check like this,
PendingIntent pi = PendingIntent.getActivity(context, new Random().nextInt(1000000), notification, PendingIntent.FLAG_UPDATE_CURRENT);

Stopping alarm and alarm ringtone together

I am developing an alarm app.
When it fires an alarm it throws notification with a disable button.
So when i click on the disable button it should stop the alarm ringtone and the alarm also.
so when i click on disable button it call the below method.
It stops the alarm.
But i want to know will this ringtone alive for next date with same time or it will remove the alarm forgood?
public void dismissRingtone() {
// stop the alarm rigntone
Intent i = new Intent(this, RingtonePlayingService.class);
stopService(i);
// also dismiss the alarm to ring again or trigger again
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
aManager.cancel(pendingIntent);
// Canceling the current notification
NotificationManager notificationManager =
(NotificationManager)getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
notificationManager.cancel(321);
}
Try, it will cancel future alarms.
Intent intentAlarm = new Intent(this, AlarmReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// Set the alarm for a particular time.
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
try {
pendingIntent.cancel();
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
e.printStackTrace();
}

Save variable with alarm manager event

I'm building a study planner application for Android, i have the AlarmManager set up and working to trigger a notification when the time elapses, which works fine.
When setting the alarm, the alarm details are saved into an SQLite database, when the alarm is set off, i need to recall the alarm information, is there some form of variable i can save into the database and link to the specific alarm so that i can use it in an SQLite query to find the correct entry.
UPDATE Code below:
Long nIdLong = System.currentTimeMillis();
String nId = nIdLong.toString();
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
alarmIntent.putExtra("nID", nId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent , 0);
AlarmManager alarmManager = (AlarmManager)getActivity().getSystemService(getActivity().ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
AlarmReciever:
public void onReceive(Context context, Intent intent)
{
long dbId = intent.getLongExtra("nID", 0);
String notificationId = Long.toString(dbId);
Log.i("App", "called receiver method");
try{
Toast.makeText(context, notificationId, Toast.LENGTH_LONG).show();
}catch(Exception e){
e.printStackTrace();
}
}
Thanks in advance
You're sending a String through the intent, it needs a Long, this code should work.
Long nIdLong = System.currentTimeMillis();
String nId = nIdLong.toString();
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
alarmIntent.putExtra("nID", nIdLong);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent , 0);
AlarmManager alarmManager = (AlarmManager)getActivity().getSystemService(getActivity().ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
While setting the alarm, first retrieve the id which will be created while inserting alarm details to SQLite via
long uniqueId = db.insert(your query);
And put that in the intent for PendindIntent for AlarmManager
Intent alarmIntent = new Intent(this, AlarmEventReceiver.class);
alarmIntent.putExtra("dbId", uniqueId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent , 0);
Inside the onReceive() of AlarmEventReceiver, you can get the id & retrieve the data from DB.
#Override
public void onReceive(Context context, Intent intent) {
long dbId = intent.getLongExtra("dbId", 0);
}

Cancel alarm with different context

I've a alarm created in an OnBootReceiver like this:
public class OnBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent i = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), savedIntervalAutomaticMilisInt, pendingIntent);
}
}
But to cancel it, I use this code in an Activity:
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
scManager.clearErrors();
So to set it up I use the context from the BroadcastReceiver's Context parameter, but to cancel it I use the this context from the Activity. My question: Will the alarm still be cancelled, even though the context is slightly different?
Will the alarm still be cancelled, even though the context is slightly different?
Context does not matter in this case -- it is merely a way to get to an AlarmManager.
Your choice of PendingIntent.FLAG_CANCEL_CURRENT in your cancel-the-alarm logic may cause a problem. If you run into difficulties (e.g., adb shell dumpsys alarm indicates your alarm survived the cancel), try replacing PendingIntent.FLAG_CANCEL_CURRENT with 0.
Give this a try for a global (application-wide) context object: android.content.ContextWrapper.getApplicationContext()

Categories

Resources