AlarmManager gets send on initial setup - android

I am having trouble with my app, that on first launch i want to setup an alarmintent and I want the alarm manager to send me a notification every 24 hour at a specific time.
Every thing about it works, except when i launch the app for the first time (when data is cleared from the app), then there is send a notification right away, which it should not do until the next time the clock hits 09:00.
Here is the function that setup the alarm (only called the very first time the app is running)
public void setAlarm(){
Toast.makeText(this, "setAlarm()", Toast.LENGTH_LONG).show();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Intent alarmIntent = new Intent(this, AlertReceiver.class);
if(PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_ONE_SHOT) != null){
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
And here is the notification function of the broadcast receiver
public void createNotification(Context context, String msg, String msgText, String msgAlert){
PendingIntent notificIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setSmallIcon(R.drawable.ic_stat_dmq_notification_icon);
mBuilder.setTicker(msgAlert); //Ticker!
mBuilder.setWhen(System.currentTimeMillis());
mBuilder.setContentTitle(msg); //Title:
mBuilder.setContentText(msgText); //Text
mBuilder.setContentIntent(notificIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(uniqueId, mBuilder.build());
I have been looking at this for days, and I cannot seem to figurer it out nor can i find a solution. If anyone can help I would be a happy man!

Is it past 9am in your area. That might be the source of your error. An Alarm set to a time in the past in android fires off right away. Try:
calendar.set(Calendar.YEAR, 2017);
Insane just for testing

Okay i manage to figure it out after all.
Only thing needed to be added was after alle the calendar.set was
if(calendar.getTimeInMillis() < System.currentTimeMillis()){
Toast.makeText(this,"1 day have been added", Toast.LENGTH_SHORT).show();
calendar.add(Calendar.DATE, 1);
}
It basically just check to see if the time was in the past, and if it was, then it adds another day, so the alarm will go off the next day.

Related

Android scheduling repeating alarms with broadcast receiver

I have to send 3 different notification(different content) at different time in a day.
Following the official documentation, https://developer.android.com/training/scheduling/alarms.html#type,
I was able to send notification at specified times, but having some trouble with changing the content of each notification. Following is the method to set notifications and is called in onCreate() method of MainActivity.
public void setNotification() {
Intent intent = new Intent(this, MyBroadcastReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
for (int id = 0; id < 3; id++) {
Calendar calendar = Calendar.getInstance();
// Defining different pendingIntent
switch (id){
case 0:
calendar.set(Calendar.HOUR_OF_DAY, 9);
break;
case 1:
calendar.set(Calendar.HOUR_OF_DAY, 14);
break;
case 2:
calendar.set(Calendar.HOUR_OF_DAY, 20);
break;
}
if(calendar.getTimeInMillis() < System.currentTimeMillis()){
calendar.add(Calendar.DATE, 1);
}
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, 0);
// setRepeating() schedules an alarm
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
I am aware that I can use Intent.putExtra() features to send data, which can be used to identify the intent, but this data will be lost if app is killed.
I want this to work even if app is not running or app gets killed or device is booted. After some reading I found out that I can use a BOOT_COMPLETE listener to set alarms after device is booted. Because of setting notifications in onCreate() method, notification is appearing everytime I run the app, even though I tried to tackle this by using following code
if(calendar.getTimeInMillis() < System.currentTimeMillis()){
calendar.add(Calendar.DATE, 1);
}
Currently onReceive method looks like this
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.app_icon)
.setContentTitle("Title")
.setContentText("Message");
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
I need help in deciding where should I put setNotification() method so that it registers all alarms once and how to identify which intent is coming so that appropriate actions can be taken. One way to go about it is to define 3 different broadcastReceivers with intent filters and set intent URI while creating them. Is it the correct way or is there any other simple solution?
notification is appearing everytime I run the app,
Keep a check using SharedPreference and set only once if not done.
Also your code
if(calendar.getTimeInMillis() < System.currentTimeMillis()){
calendar.add(Calendar.DATE, 1);
}
should be somewhat like this
Calendar calendar = Calendar.getInstance();
// Get the current time in millis
long currentTime = calendar.getTimeInMillis();
// Set the reminder times
switch(id) {
..
..
}
//Get the reminder time in millis
long intendedTime = calendar.getTimeInMillis();
if (intendedTime < currentTime) {
// Set from next day and to repeat once a day.
// you might consider using calendar.add() for adding one day to the current day
calendar.add(Calendar.DAY_OF_MONTH, 1);
intendedTime = calendar.getTimeInMillis();
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
// Set for today and to repeat once a day.
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, intendedTime,
AlarmManager.INTERVAL_DAY, pendingIntent);
}
how to identify which intent is coming so that appropriate actions can
be taken
You need to set an action to Intent in order to receive data in BroadcastReceiver
Intent intent = new Intent(this, MyBroadcastReceiver.class);
intent.setAction("THIS_IS_MY_ACTION");
Case of BOOT_COMPLETE
Cancel all the alarm on Boot, and reset them. To cancel an alarm Call cancel() on AlarmManager with an same PendingIntent which you have used while setting an alarm using setRepeating().
Take care of context and INTENT_FLAGS while working with AlarmManager.
Use getApplicationContext() for context and Keep records of request_code as they are going to be used while cancelling an alarm, use PendingIntent.FLAG_UPDATE_CURRENT
This might help:-
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), request_code, intent, PendingIntent.FLAG_UPDATE_CURRENT)

Issue with AlarmReceiver Android

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!

How to set reminders in android using background service?

Hi I am working on a application where I am getting reminder details from user as reminder Date and reminder name and storing those in database. Now I want to know how can I start reminder through background service? Or Is there any other way if yes please tell me. What should I do? Please help me. Suggest something or tutorial will be great idea.
Thanks in advance!
For this you will require two things
Alarm manager: To set the time for notification or alarm (daily, weekly basis)
Service: To launch your notification when alarm manager goes off
Do this in your activity class where you want to set the reminder
Intent myIntent = new Intent(this , NotifyService.class);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
//get time from database and initialise the variables.
int minute;
int hour;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.HOUR, hour);
calendar.set(Calendar.AM_PM, Calendar.AM); //set accordingly
calendar.add(Calendar.DAY_OF_YEAR, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pendingIntent);
This will trigger Alarm each day at your set time.
Now, you should create a Service as NotifyService and put the following code in its onCreate():
#Override
public void onCreate() {
NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.notification_icon, "Notify Alarm strart", System.currentTimeMillis());
Intent myIntent = new Intent(this , MyActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
notification.setLatestEventInfo(this, "Notify label", "Notify text", contentIntent);
mNM.notify(NOTIFICATION, notification);

How can I test timed Notification? Or is my code somehow wrong?

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.

Set notification to specific time

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.

Categories

Resources