Repeating Alarm not working - android

I know this type of questions are aksed so many times...but please first read my question before down voting or marking as duplicate.
I have referred so many SO questions like this for managing alarm but cant find any solution so i am here.
In my app i want to trigger repeating alarm one at daily 8.00 am and others as user specified.
First i tired to repeat alarm using setRepeating...this is my code
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM,Calendar.AM);
//calendar.set(Calendar.MILLISECOND, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent pintent = new Intent(this, AlarmReceiver.class);
pintent.putExtra("id", 0);
pintent.putExtra("ontime", false);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
pintent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
Actually the problem is alarm is not firing after long sleep. If it test using changing date and time it fires perfactly....but it stops firing after a night...
So i switched to second option as mentioned in given link. I set alarm using setExact as follow and reschedule it on each fire.
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM,Calendar.AM);
//calendar.set(Calendar.MILLISECOND, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent pintent = new Intent(this, AlarmReceiver.class);
pintent.putExtra("id", 0);
pintent.putExtra("ontime", false);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
pintent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), pendingIntent);
am.setAlarmClock(alarmClockInfo, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
am.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
But steel i am having same issue. It is not repeating daily. Please also consider this is only the example of my default alarm. There can be N no of exact and repeating alarms as user specified.
Someone also suggest me to use service rather than alarm manager, but my service might be killed so i am afraid to use that. One other solution is to check due date and set all alarm daily, but i dont think this is the right way. Is it?
Please suggest me any other method or help me to improve my code. I badly need this to work. Thanx all. My testing devices are HTC One X (4.3), Redmi Prime(6.0) and Mi4i (5.0.2)

I had many problems setting repeating alarms, but in the end this code was working on all my testing devices, maybe this helps:
// set time
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
c.set(Calendar.HOUR_OF_DAY, 8);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
long startUpTime = c.getTimeInMillis();
// startupTime + 24 hours if alarm is in past
if (System.currentTimeMillis() > startUpTime) {
startUpTime = startUpTime + 24 * 60 * 60 * 1000;
}
// initialize alarm
AlarmIntent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, 0);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, startUpTime, 24 * 60 * 60 * 1000, pendingIntent);

Related

Alarm not working (android) interval_day

I am trying to create two alarms, one that starts my service at 7:00 p.m every day, and one that stop it at 5:00 a.m. every day. I have tested my alarm over and over and it seems interval_day does not seem to work. If I replace AlarmManager.INTERVAL_DAY with 60*1000 the alarm goes off, but with AlarmManager.INTERVAL_DAY it does not go off. I have the other alarm which uses the same code and AlarmManager.INTERVAL_DAY works with it. Any idea why that one works and the other one doesn't? How would I fix this?
EDIT: It turns out that both alarms are not working at the same time, either one or the other turns on or none at all. Is there something wrong with my code for having two alarms? Can I have only one alarm at a time? Changing the interval to 60 seconds seems to make that alarm go off 100%, but otherwise it seems they go off only 30% of the time and never both. I have no clue what might be causing this.
//code that does not go off and doesnt work
public void setAlarm(){
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, DrawOverAppsService.class);
Float alpha2 = alpha.getProgress()/100f;
intent.putExtra("alpha", alpha2);
PendingIntent alarmIntent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
if(start.isChecked()) {
alarmMgr.cancel(alarmIntent);
java.util.Calendar calendar = java.util.Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(java.util.Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
Log.d("a","b");
}
if(start.isChecked() == false) {
alarmMgr.cancel(alarmIntent);
}
}
//code that goes off and works
public void stopAlarm(){
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, stopOverlay.class);
PendingIntent alarmIntent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
if(stop.isChecked()) {
alarmMgr.cancel(alarmIntent);
java.util.Calendar calendar = java.util.Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(java.util.Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
if(stop.isChecked() == false) {
alarmMgr.cancel(alarmIntent);
}
}

Android Alarm Scheduling Efficient

I want to scheduler alarms which should trigger daily on given time. They should be 100% consistent. Currently I am using
AlamManager.setInexactRepeating
and it works a day but not next day and itself starts another day , i mean its not consistent.
So what should I use in Android AlarmManager which trigger must trigger daily and should be efficient ?
This code will run the Intent each day on 1 PM or 2 PM. Hope that helps you.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 13); // For 1 PM or 2 PM
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
PendingIntent pi = PendingIntent.getService(context, 0,
new Intent(context, MyClass.class),PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pi);

Android set alarmManager to trigger daily

In my app, I need to start a service at 2:00pm daily. Right now I wrote the code to trigger the alarm once, this code is ran every time I open the app:
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, DownloadReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.cancel(pIntent);
Calendar cal= Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR_OF_DAY,refreshhour);
cal.set(Calendar.MINUTE,refreshmin);
cal.set(Calendar.SECOND, 0);
// if the scheduler date is passed, move scheduler time to tomorrow
if (System.currentTimeMillis() > cal.getTimeInMillis()) {
cal.add(Calendar.DAY_OF_YEAR, 1);
}
if(android.os.Build.VERSION.SDK_INT>=23) {
alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pIntent);
}
else{
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pIntent);
}
Q1. I used setAndAllowWhileIdle() for sdk above 23 in case the device is in Doze mode. I cannot find any option in this function that I can set the alarm to repeat every day.
Q2. I also have questions about setInexactRepeating() , normally it is set to repeat every day by setting the parameter INTERVAL_DAY , but in the docs, it says
As of API 19, all repeating alarms will be inexact and subject to
batching with other alarms regardless of their stated repeat interval.
Does this mean INTERVAL_DAY does not work anymore, so how can I set the alarm daily without rerunning this function and reset alarmManager?
Try below code will solve your problem-
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
boolean flag = (PendingIntent.getBroadcast(this, 0,
new Intent("totime.action.string"),
PendingIntent.FLAG_NO_CREATE) != null);
if(!flag)
{
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent("totime.action.string");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) Data_Graph.this.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),(24*60*60*1000), pendingIntent);
}

Alarm gets trigger randomly but not daily

The below code triggers alarm randomly at any time, but I want to trigger it only at 8 AM and daily.
What I am missing, please help. Thanks in advance.
Intent alarmIntent = new Intent(context, NotifyingDailyService.class);
PendingIntent alarmPIntent = PendingIntent.getService(context, 0, alarmIntent, 0);
// Set the alarm to start at approximately 8:00 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
AlarmManager alarmMgr= (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.cancel(alarmPIntent);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmPIntent);
I believe AlarmManager.INTERVAL_DAY is only appropriate for calls to setInexactRepeating(). I think you need to change AlarmManager.INTERVAL_DAY to the number of milliseconds in a day.
INTERVAL_DAY DOCUMENTATION
http://developer.android.com/reference/android/app/AlarmManager.html#INTERVAL_DAY
ALARM MANAGER EXAMPLE
Android: How to repeat a service with AlarmManager every 15 minutes, but only run from 8:00AM to 18:00PM?
I solved the question myself by using broadcast rather than service.
Intent alarmIntent = new Intent(context, DailyNotificationAlarmReceiver.class);
PendingIntent alarmPIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
// Set the alarm to start at approximately 8:00 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
//System.out.println("Alarm set at 8 clock");
Toast.makeText(context, "Alarm set at 8 clock", Toast.LENGTH_LONG).show();
AlarmManager alarmMgr= (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.cancel(alarmPIntent);
//alarmMgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmPIntent);
//alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),calendar.getTimeInMillis()+ DateUtils.DAY_IN_MILLIS, alarmPIntent);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, alarmPIntent);

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.

Categories

Resources