In my app I use alarm manager to daily show notifications, but I want to create an option for users to cancel the daily notifications.On user click the working alarm manager has to permanently stop.
How to achieve this?
This is the method that is being called on app installation and then notification starts appearing daily, how to cancel it permanently?
public void AlaramNotification() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(StartActivity.this, AlarmReceiver.class);
PendingIntent broadcast = PendingIntent.getBroadcast(StartActivity.this,
0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
cal = Calendar.getInstance();
Calendar now = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 15);
cal.add(Calendar.SECOND, 0);
cal.set(Calendar.AM_PM,Calendar.AM);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (now.after(cal)) {
Log.d("Hey","Added a day");
cal.add(Calendar.DATE, 1);
}
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), broadcast);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 24*60*60*1000, broadcast);
}
else {
}
}
You can try this way:
AlarmManager alarmManager =
(AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(StartActivity.this, AlarmReceiver.class);
PendingIntent broadcast = PendingIntent.getActivity(StartActivity.this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(broadcast);
When user cancels daily notification use cancel() on alarmManager with pendingintent as shown below to stop alarmManager.
alarmManager.cancel(broadcast);
You may need to make broadcast a global variable.
Introduction:
Through a ToggleButton I make my user to enable or disable the alarm reminder. The alarm remember my user to record their activity one hour after the last time he has entered the app also do not want the alarm to sound at night. This all works fine.
public void each_hour_alarm() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour <= 20 && hour >= 7) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
notificationIntent.addCategory("android.intent.category.DEFAULT");
PendingIntent broadcast = getBroadcast(getApplicationContext(), 100, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR, 1);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast);
stop_alarm_9am();
}else {
stop_each_hour_alarm();
alarm_9am();
}
}
The problem begins when I call a new method: alarm_9am();
The new method raises an alarm at 9 am if the user has not entered before the app. This is where I have the problem. The alarm sounds at 9am, but also, and this is my problem, it also sounds every time I log activity between 21h and 23: 59h.
I do not understand why this happens. Any ideas??
This is de code:
public void alarm_9am() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent("android.media.buenosdias.action.DISPLAY_NOTIFICATION");
notificationIntent.addCategory("android.intent.buenosdias.category.DEFAULT");
PendingIntent broadcast = getBroadcast(getApplicationContext(), 100, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast);}
Code to stop alarm_9am();
public void stop_alarm_9am() {
Intent intentlocal = new Intent("android.media.buenosdias.action.DISPLAY_NOTIFICATION");
intentlocal.addCategory("android.intent.buenosdias.category.DEFAULT");
PendingIntent pilocal = getBroadcast(getApplicationContext(), 100, intentlocal, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pilocal);
pilocal.cancel();
}
And my AlarmReceiver;
public class AlarmReceiver_buenos_dias extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent notificationIntent = new Intent(context, v_agua.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(v_agua.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Notification notification = builder.setContentTitle("Good Morning")
.setContentText("Begin New Day")
.setTicker("Go to app")
.setSmallIcon(R.drawable.logo_launcher_a)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setStyle(new NotificationCompat.BigTextStyle().bigText(""))
.setAutoCancel(true)
.setContentIntent(pendingIntent).build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}}
My issue is that the alarm sounds between 21h to 23:59 every time I enter in activity and i dont know why. I need not sound the alarm every time I log in activity between 21h and 23:59, I just want alarm_9am(); sounds at 9am
Thanks!
I want to fire different notifications when a specific alarmManager is reached.
For example I want to display "independence day" when we reach the date of Independence stored in a certain alarmManager, and to display "Steve jobs died" when we reach the date of his death stored in another Alarm Manager, and so on.
So my question is how to link each alarmManager(cal and cal2) with different notification?
I did this until now,
in MainActivity:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE,19);
cal.set(Calendar.MONTH,11);
cal.set(Calendar.YEAR,2015);
cal.set(Calendar.HOUR_OF_DAY, 21);
cal.set(Calendar.MINUTE, 42);
cal.set(Calendar.SECOND, 30);
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.DATE,19);
cal2.set(Calendar.MONTH,11);
cal2.set(Calendar.YEAR,2015);
cal2.set(Calendar.HOUR_OF_DAY, 21);
cal2.set(Calendar.MINUTE, 43);
cal2.set(Calendar.SECOND, 10);
Intent alertIntent = new Intent(this, AlertReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), PendingIntent.getBroadcast(this, 1, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
alarmManager.set(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), PendingIntent.getBroadcast(this, 2, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
notice that I made to dates to fire notification and it is working, the notification in onReceive was fired twice, the first time when I reach "cal" and for the second time when I reach "cal2". But as I mentioned above, I need to fire a different notification when I reach cal2
this is the OnReceive:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
createNotification(context, "title1", "independence day", "event of today");
//here i want to link this notification with AlarmManager containing Cal as a date
createNotification(context, "title2", "steve jobs died", "event of today");
//here i want to link this notification with AlarmManager containing Cal2 as a date
}
public void createNotification(Context context, String msg, String msgText, String msgAlert) {
PendingIntent notificIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.not)
.setContentTitle(msg)
.setTicker(msgAlert)
.setContentText(msgText);
//intent to fire when notification clicked on
mBuilder.setContentIntent(notificIntent);
//how the person will be notified
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
//cancel notification when clicked in the taskbar
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager= (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0,mBuilder.build());
}
after applying what mentioned below: i made this 4 events:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alertIntent = new Intent(this, AlertReceiver.class);
alertIntent.putExtra("title", "event1");
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), PendingIntent.getBroadcast(this, 1, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Intent alertIntent2 = new Intent(this, AlertReceiver.class);
alertIntent2.putExtra("title", "event2");
alarmManager.set(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), PendingIntent.getBroadcast(this, 2, alertIntent2, PendingIntent.FLAG_UPDATE_CURRENT));
Intent alertIntent3 = new Intent(this, AlertReceiver.class);
alertIntent3.putExtra("title", "event3");
alarmManager.set(AlarmManager.RTC_WAKEUP, cal3.getTimeInMillis(), PendingIntent.getBroadcast(this, 3, alertIntent3, PendingIntent.FLAG_UPDATE_CURRENT));
Intent alertIntent4 = new Intent(this, AlertReceiver.class);
alertIntent4.putExtra("title", "event4");
alarmManager.set(AlarmManager.RTC_WAKEUP, cal4.getTimeInMillis(), PendingIntent.getBroadcast(this, 4, alertIntent3, PendingIntent.FLAG_UPDATE_CURRENT));
and in OnReceive:
createNotification(context,intent.getStringExtra("title"), "event", " event");
sometimes for the first time running the application all the events appear, sometimes the 3rd appear twice, and the first two do not appear, sometimes just the last one appear, so there is something wrong or messy in my code,
whats the problem?
calendar:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE,24);
cal.set(Calendar.MONTH,11);
cal.set(Calendar.YEAR,2015);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 55);
cal.set(Calendar.SECOND, 10);
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.DATE,24);
cal2.set(Calendar.MONTH,11);
cal2.set(Calendar.YEAR,2015);
cal2.set(Calendar.HOUR_OF_DAY, 23);
cal2.set(Calendar.MINUTE, 55);
cal2.set(Calendar.SECOND, 20);
Calendar cal3 = Calendar.getInstance();
cal3.set(Calendar.DATE,24);
cal3.set(Calendar.MONTH, 11);
cal3.set(Calendar.YEAR,2015);
cal3.set(Calendar.HOUR_OF_DAY, 23);
cal3.set(Calendar.MINUTE, 55);
cal3.set(Calendar.SECOND, 30);
Calendar cal4 = Calendar.getInstance();
cal4.set(Calendar.DATE,24);
cal4.set(Calendar.MONTH, 11);
cal4.set(Calendar.YEAR,2015);
cal4.set(Calendar.HOUR_OF_DAY, 23);
cal4.set(Calendar.MINUTE, 55);
cal4.set(Calendar.SECOND, 40);
You can pass that information along with the intent while scheduling the alarm.
Intent alertIntent = new Intent(this, AlertReceiver.class);
alertIntent.putExtra("Notification Key", 1);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), PendingIntent.getBroadcast(this, 1, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
And in your onReceive check the value and show the notification based on that:
Integer notificationId = intent.getIntExtra("Notification Key", -1);
if (notificationId == 1)
{
// Show indipendente day
}
else
{
// do something else
}
Instead of passing integer value, you can also pass the notification message and show it directly without any if...else condition.
Passing string data:
alertIntent.putExtra("Notification Key", "Independence day");
Getting string back:
String message = intent.getStringExtra("Notification Key");
// Calling the notification
createNotification(context, "title1", message, "event of today");
You could make different intents and make
intent.putExtra("title","independence day");
and also make a separate id for every notification you could do it like this.
alertIntent.putExtra("id", 1);
and in onReceive change to:
createNotification(context, intent.getStringExtra("title"), "event", " event",intent.getIntExtra("id", 0));
and the method
public void createNotification(Context context, String msg, String msgText, String msgAlert,int id) {
//your code and change this line bellow
mNotificationManager.notify(id,mBuilder.build());
}
so it will look like this:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alertIntent = new Intent(this, MyReceiver.class);
alertIntent.putExtra("title", "event1");
alertIntent.putExtra("id", 1);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), PendingIntent.getBroadcast(this, 1, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Intent alertIntent2 = new Intent(this, MyReceiver.class);
alertIntent2.putExtra("title", "event2");
alertIntent2.putExtra("id", 2);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), PendingIntent.getBroadcast(this, 2, alertIntent2, PendingIntent.FLAG_UPDATE_CURRENT));
Intent alertIntent3 = new Intent(this, MyReceiver.class);
alertIntent3.putExtra("title", "event3");
alertIntent3.putExtra("id", 3);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal3.getTimeInMillis(), PendingIntent.getBroadcast(this, 3, alertIntent3, PendingIntent.FLAG_UPDATE_CURRENT));
Intent alertIntent4 = new Intent(this, MyReceiver.class);
alertIntent4.putExtra("title", "event4");
alertIntent4.putExtra("id", 4);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal4.getTimeInMillis(), PendingIntent.getBroadcast(this, 4, alertIntent4, PendingIntent.FLAG_UPDATE_CURRENT));
I want to deliver timed notifications (everyday, 5:00AM), and tried to do this using AlarmManager with the following code:
Intent appIntent = new Intent(this, NotificationService.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent penIntent = PendingIntent.getService(this, 0,
appIntent, 0);
alarmManager.cancel(penIntent);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 5);
cal.set(Calendar.MINUTE, 00);
cal.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, penIntent);
The NotificationService.class looks (at least the important parts) like this:
int id = 001;
NotificationManager mNotifyMng = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
MainActivity.this).setSmallIcon(R.drawable.icon).setContentTitle("Test")
.setContentText("Test!");
mNotifyMng.notify(id, mBuilder.build());
stopSelf();
I can't seem to get it to work. When I set the emulator clock to 4:59 or something and wait for it to change to 5:00, there is no notification showing up and I can't figure another way to test it.
I hope you know some way to test it or find the bug in my code.
I believe the problem is that you cancel the PendingIntent but then you need to recreate it again before setting alarmManager.
//cancel pendingIntent
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent penIntent = PendingIntent.getService(this, 0,appIntent, 0);
alarmManager.cancel(penIntent);
//reset pendingIntent
Intent appIntent = new Intent(this, NotificationService.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent penIntent = PendingIntent.getService(this, 0,appIntent, 0);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 5);
cal.set(Calendar.MINUTE, 00);
cal.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC, cal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, penIntent);
To cancel a PendingIntent you need to create it exactly as you did the first time then call AlarmManagers cancel() on it as you are. But then you need to create it again to set the alarm on the PendingIntent
**I hope you know some way to test...
There may be a better way but, for testing purposes, I will sometimes set a global debug flag which will change times between testing and production. So say 4 hours might be 2 minutes. Times of the day may be a little more tricky but you can change the time to whatever hour, minute, or whatever is close. Once you know it is triggering at the right time then you can change it back and still test when that time of day comes around but you now know it should be working.
I would like my notification to run at 12:00pm everyday. How do you replace the when value with a time?
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notify = new Notification(R.drawable.icon,"Its Time to Eat",when);
Context context = GrubNOWActivity.this;
CharSequence title = "Its Time to Eat";
CharSequence details = "Click Here to Search for Restaurants";
Intent intent = new Intent(context,Search.class);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
notify.setLatestEventInfo(context, title, details, pending);
nm.notify(0,notify);
You can use an alarm manager
Intent myIntent = new Intent(ThisApp.this , myService.class);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getService(ThisApp.this, 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000 , pendingIntent); //set repeating every 24 hours
and put the notification inside myService class!
The when parameter is for sorting the notifications in the status bar. You should code your app such that it fires the notification at the desired time.