I am trying to create a simple alarm application where alarm should go off on several days.
I have created a service which registers alarm manager based on data saved in preferences. Everything is working fine except that it does not trigger alarm when app is not running.
AlarmService.java
#Override
protected void onHandleIntent(Intent intent) {
Toast.makeText(this,"Service started",Toast.LENGTH_LONG);
//set separate pending intent values for all days
setIntents();
// register the alarm manager here
alarmManager = (AlarmManager)(getSystemService(Context.ALARM_SERVICE));
execute();
}
private void execute() {
prefs=getSharedPreferences("user_data_pref",Context.MODE_PRIVATE);
prefEditor=prefs.edit();
int hour=prefs.getInt("ALARM_HOUR",0);
int minute=prefs.getInt("ALARM_MINUTE",0);
if(prefs.getString("ALARM_STATUS","NOT_SET").equals("SET"))
isAlarmOn=true;
if(prefs.getString("NOTIFICATION_STATUS","NOT_SET").equals("SET"))
isNotificationOn=true;
if (prefs.getBoolean("MON_SET",false)) {
setAlarmFor(Calendar.MONDAY,hour,minute,mondayIntent,isAlarmOn,isNotificationOn);
}
if (prefs.getBoolean("TUE_SET",false)) {
setAlarmFor(Calendar.TUESDAY,hour,minute,tuesdayIntent,isAlarmOn,isNotificationOn);
}
if (prefs.getBoolean("WED_SET",false)) {
setAlarmFor(Calendar.WEDNESDAY,hour,minute,wednesdayIntent,isAlarmOn,isNotificationOn);
}
if (prefs.getBoolean("THU_SET",false)) {
setAlarmFor(Calendar.THURSDAY,hour,minute,thursdayIntent,isAlarmOn,isNotificationOn);
}
if (prefs.getBoolean("FRI_SET",false)) {
setAlarmFor(Calendar.FRIDAY,hour,minute,fridayIntent,isAlarmOn,isNotificationOn);
}
if (prefs.getBoolean("SAT_SET",false)) {
setAlarmFor(Calendar.SATURDAY,hour,minute,saturdayIntent,isAlarmOn,isNotificationOn);
}
if (prefs.getBoolean("SUN_SET",false)) {
setAlarmFor(Calendar.SUNDAY,hour,minute,sundayIntent,isAlarmOn,isNotificationOn);
}
}
private void setAlarmFor(int weekday, int hour, int minute, PendingIntent pendingIntent, boolean isAlarmOn, boolean isNotificationOn){
if(isAlarmOn){
prefEditor.putString("ALARM_STATUS","SET");
prefEditor.commit();
}
if(isNotificationOn){
prefEditor.putString("NOTIFICATION_STATUS","SET");
prefEditor.commit();
}
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK,weekday);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND,0);
/* Repeating on every week interval */
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
7*24*60*60*1000, pendingIntent);
}
private void setIntents(){
Intent intent = new Intent(this,AlarmReceiver.class);
mondayIntent=PendingIntent.getBroadcast(this, Calendar.MONDAY, intent, 0);
tuesdayIntent=PendingIntent.getBroadcast(this, Calendar.TUESDAY, intent, 0);
wednesdayIntent=PendingIntent.getBroadcast(this, Calendar.WEDNESDAY, intent, 0);
thursdayIntent=PendingIntent.getBroadcast(this, Calendar.THURSDAY, intent, 0);
fridayIntent=PendingIntent.getBroadcast(this, Calendar.FRIDAY, intent, 0);
saturdayIntent=PendingIntent.getBroadcast(this, Calendar.SATURDAY, intent, 0);
sundayIntent=PendingIntent.getBroadcast(this, Calendar.SUNDAY, intent, 0);
}
It should trigger AlarmReceiver class that displays alarm.
AlarmReceiver.java
#Override
public void onReceive(Context context, Intent intent) {
prefs=context.getSharedPreferences("user_data_pref",Context.MODE_PRIVATE);
//Get Status of currently set alarm and notification
alarmStatus=prefs.getString("ALARM_STATUS","NOT_SET");
notificationStatus=prefs.getString("NOTIFICATION_STATUS","NOT_SET");
//Send notification if the notification is set
if(notificationStatus.equals("SET")){
Toast.makeText(context, "NOTIFICATION START SUCCESSFUL", Toast.LENGTH_SHORT).show();
playNotificationSound(context,getNotificationSound());
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setContentTitle("") // title for notification
.setContentText("") // message for notification
.setAutoCancel(true); // clear notification after click
Intent intent_1 = new Intent(context, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 11, intent_1, Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
displayNotification(context);
}
//Fire Alarm if the Alarm is set
if(alarmStatus.equals("SET")){
Toast.makeText(context, "ALARM START SUCCESSFUL", Toast.LENGTH_SHORT).show();
/** Creating Alarm */
Intent i = new Intent(context,FitterfoxAlarmActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
AndroidManifest.xml
<receiver android:name=".OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".AlarmReceiver"></receiver>
<service android:name=".AlarmService"></service>
Try this set of code your service never going to stop it's works for me. "alarmManager.setRepeating" not working in many of the lollipop and marshmallows device once it started then lose control over the service this will help you out.
if (android.os.Build.VERSION.SDK_INT >= 23) {
piLR = PendingIntent.getBroadcast(context, 0, intentLR,
PendingIntent.FLAG_UPDATE_CURRENT);
amLR.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval, piLR);
} else if (android.os.Build.VERSION.SDK_INT >= 19
&& android.os.Build.VERSION.SDK_INT < 23) {
piLR = PendingIntent.getBroadcast(context, 0, intentLR,
PendingIntent.FLAG_UPDATE_CURRENT);
amLR.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), interval, piLR);
} else {
amLR.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), interval, piLR);
}
Starting with KitKat, changes were made to the AlarmManager to improve device battery life. The time at which alarms fire is less exact. If you want your alarms to fire within minutes of the scheduled time, you will need to change the way you are using AlarmManager.
For KitKat (API 19) and later builds, the times specified in setRepeating() are inexact, as described in the documentation. The docs also note:
If your application needs precise delivery times then it must use
one-time exact alarms, rescheduling each time.
You indicate that the alarms do not fire when the app is not running. Because the period for your alarms is one week, there can be a large difference between the scheduled time and the actual time the alarm is fired. The documentation indicates:
Your alarm's first trigger will not be before the requested time, but
it might not occur for almost a full interval after that time.
I suspect that with your current code, you would eventually see the alarm fire, but might have to wait a very long time after the expected time.
Your revised code will probably need to use setWindow().
Marshmallow introduced Doze mode, which further changes alarm scheduling. As #Andy noted in his answer, to get the beavior you want on Marshmallow and later devices, you will need to use setExactAndAllowWhileIdle().
Two other things that need to be fixed. Your PendingIntents should probably use flag PendingIntent.FLAG_UPDATE_CURRENT. In your receiver, the flag Intent.FLAG_ACTIVITY_NEW_TASK belongs on intent_1, not pi.
Related
my mean goal is to run a task periodically at midnight (00:00:00)
but the user can set the period based on the interval (daily, weekly , monthly)
let's assume that this job is a backup Scheduling.
this task will triggred at midnight but based on the user preference (midnight everyday, every week , or monthly ), and if the phone was in the doze mode or even off , wait untill the next start and start backup.
when i start implementing the code , i started with JobService and JobScheduler , but unfortunately i learned that i can set the repetitive but i can't set the exact time, so the last solution was to work with alarmmanager.
i use this code for triggering the alarm :
public static void setTheTimeToStartBackup(Context context,String periode) {
int DATA_FETCHER_RC = 123;
AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
Intent intent = new Intent(context, BackUpAlarmRecevier.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, DATA_FETCHER_RC,intent, PendingIntent.FLAG_UPDATE_CURRENT);
long interval = 0;
switch (periode){
case "never":
return;
case "daily":
alarmStartTime.set(Calendar.HOUR_OF_DAY, 0);
interval = AlarmManager.INTERVAL_DAY;
break;
case "weekly":
alarmStartTime.set(Calendar.DAY_OF_WEEK, 1);
interval = AlarmManager.INTERVAL_DAY*7;
break;
case "monthly":
alarmStartTime.set(Calendar.WEEK_OF_MONTH, 1);
interval = AlarmManager.INTERVAL_DAY*30;
break;
}
alarmStartTime.set(Calendar.HOUR_OF_DAY, 0);
alarmStartTime.set(Calendar.MINUTE, 0);
alarmStartTime.set(Calendar.SECOND, 0);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),interval, pendingIntent);
Log.e("Alarm","Set for midnight");
}
this is my receiver :
public class BackUpAlarmRecevier extends BroadcastReceiver {
SharedPreferences preferences;
#Override
public void onReceive(Context context, Intent intent) {
Log.e("BackUpAlarmReciver","Triggred");
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG:APP");
wl.acquire();
sendNotification(context);// simple notification...
Toast.makeText(context, "Alarm !!", Toast.LENGTH_LONG).show();
startBackupProcess();
wl.release();
}}
the problem is task never start.
so i went to test it with less time interval (15min as the minimum possible as i read ), so i change my first function setTheTimeToStartBackup to this :
public static void setTheTimeToStartBackup(Context context,String periode) {
int DATA_FETCHER_RC = 123;
AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 55);
Intent intent = new Intent(context, BackUpAlarmRecevier.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, DATA_FETCHER_RC,intent, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
Log.e("Alarm","Set for midnight");
}
and exactly the same problem , nothing started, no log , no notification , nothing.
and i already set the Receiver in my manifest with all permission like that :
<receiver android:name=".job.BackUpAlarmRecevier"
android:enabled="true"
android:process=":remote"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
what im doing wrong in both cases ? and if it work , this code will persist for ever or i need to set it again each time ?
thanks :)
EDIT:
i call my function setTheTimeToStartBackup in the MainActivity.
You could set it to occur at midnight if you did the appropriate time calculations. Dynamically get the current time and date, calculate when to register the broadcast for the alarm manager. Customize the onReceive method to set another alarm at 12pm again.
Either way you can trigger a broadcast receiver by registering your receiver manually.
Broadcast receiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("Alarm received!! ");
// Register alarm again here.
}
}
Code to register a receiver with a custom intent filter.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager mAlarmManager = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
getApplicationContext().registerReceiver(new AlarmReceiver(), new IntentFilter("AlarmAction"));
PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, new Intent("AlarmAction"), 0);
// Add dynamic time calculations. For testing just +100 milli.
mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 100, broadcast);
;
}
You could achieve what you wanted through a background service.
My suggestion would be to turn the problem around a bit.
Create three topics on Firebase (daily, weekly, monthly). Subscribe users to appropriate topics. Have a Firebase function that is triggered by CRON job which sends the data notification down to the device, this data notification should schedule one-time WorkManager job for the update. This way you can control everything from server-side, if the phone is off, it will still execute as soon as it turns on and you don't need to manually take care of catching the Boot completed with alarm manager etc.
I'd like to repeat an alarm every 20 minutes.
So I tried:
manifest:
<receiver android:name=".AlarmReceiver" />
AlarmReceiver.class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent2 = new Intent(context, MainActivity.class);
showNotification(context, "text", "text", intent2);
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(context, notification);
r.play();
}
#TargetApi(Build.VERSION_CODES.N)
public void showNotification(Context context, String title, String body, Intent intent) {
...
}
}
and in my main activity:
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 1200);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
It is working only the first time. I'd like to keep it repeating even when the app is not opening, any ideas?
Starting with KitKat (API 19), alarms are all inexact, meaning the system will batch alarms around similar times together. If you need exact timing, there are different APIs to call. Further complicating things, starting with Marshmallow, Android introduced the concept of Doze, which further restricts the when/how things can wake up the device. You can still use exact alarms, but need to use the API which allows it during idle (Doze) time: setAndAllowWhileIdle(). Bear in mind that when your alarm fires, you could be in a Doze window and your app will be restricted on what kinds of operations it can perform.
Try below for Repeating alarm on every 20 minutes interval
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),1000 * 60 * 20, pendingIntent);
Try to use android worker manager since it is working with doze mode as well. https://developer.android.com/reference/androidx/work/PeriodicWorkRequest#min_periodic_interval_millis
https://developer.android.com/reference/androidx/work/PeriodicWorkRequest
Since the introduction Doze Mode and App StandBy managing alarms have changed. The problem I'm facing is my alarm manager fires correctly on KitKat, Lolipop and Marshmellow devices but above API 23 it does not fire unless the app is in foreground or background. But if the app is killed, the alarms are stopped.
Checked out Google Keep Application on my Android 7, turns out it does the same.
But Google Calendar fires regardless of whether the app is killed or not.
Done some reading and found out setExactAndAllowWhileIdle method on the alarm manager ensures to break the doze mode and trigger your alarm.
But it does not work, is there anything I'm missing here?
Here's my code:
Intent alertIntent = new Intent(this, NotificationPublisher.class);
alertIntent.putExtra("Hello", "Meal Time");
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
int id = (int) System.currentTimeMillis();
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, delay, PendingIntent.getBroadcast(this, id, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, delay, PendingIntent.getBroadcast(this, id, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, delay, PendingIntent.getBroadcast(this, id, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}
Broadcast Receiver:
public class NotificationPublisher extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("Hello");
Log.d("Called", "Meal Time");
}
Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".NotificationPublisher" />
Because of battery optimisation it is not working,i turned off the battery optimisation of particular app, it is working fine in oneplus 3.
You wanna white-list your app from battery optimisation programatically, check this link stackoverflow.com/a/42651399/3752079
Try with adding below line for your alertIntent
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,myIntent, 0);
I want my user to set a time to receive a daily reminder from my app. In my ReminderActivity I create the PendingIntent and the Alarm Manager, and then in my Alarm Receiver class I create the notification inside onReceive(). I tried both the FLAG_CANCEL_CURRENT and FLAG_UPDATE_CURRENT flags when creating the pending intent but still when I am testing the app and changing the reminder time then sometimes the notification doesn't arrive at all, or it arrives only when the app is running in the background and the screen is on. I would greatly appreciate any thought or ideas.
ReminderActivity code:
private void setNotification() {
Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, chosenHour);
calendar.set(Calendar.MINUTE, chosenMinute);
calendar.set(Calendar.SECOND, 0);
//if user sets the alarm after their preferred time has already passed that day
if(now.after(calendar)) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
Intent intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(ReminderActivity.this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
Alarm Receiver code:
#Override
public void onReceive(Context context, Intent intent) {
Bitmap largeLogo = BitmapFactory.decodeResource(context.getResources(),
R.drawable.ptwired_logo);
//create local notification
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, MainActivity.class);
//notificationIntent.putExtra("FromPTWired", true); //to track if user opens the app from the daily digest notification
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ptwired_logo)
.setLargeIcon(largeLogo)
.setContentTitle(context.getResources().getString(R.string.app_name))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setContentText(REMINDER_TEXT)
.setAutoCancel(true)
.setOngoing(false)
.build();
notificationManager.notify(1, notification);
}
}
Probably an issue of Doze mode, take a look in Android restriction:
Doze restrictions
The following restrictions apply to your apps while in Doze:
Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window.
If you need to set alarms that fire while in Doze, use setAndAllowWhileIdle() or setExactAndAllowWhileIdle().
Alarms set with setAlarmClock() continue to fire normally — the system exits Doze shortly before those alarms fire.
In my app, I want to do a certain task everyday and after that task is completed I want to trigger multiple notifications at different times (these times will be calculated while doing that task).
After googling I found out that using AlarmManager is my best option:
This class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running. Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted.
My problems are:
1. Notification is shown only for that first time, not after that.
2. AlarmManager is triggered every time I restart that app and that past notification is shown.
PS.: I am a newbie in android and any help is appreciated
Here is what I tried:
Funtion in my activity from I am setting up this Alarm:
private void handleNotification() {
Intent alarmIntent = new Intent(this, AlarmReciever.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
This is my AlarmReciever class:
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ArrayList<String> times = new ArrayList();
GPSTracker gpsTracker = new GPSTracker(context);
//calculate the times arraylist
DateFormat format;
Date date = null;
for (String s : times) {
if (hour12) {
format = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
try {
date = format.parse(s);
} catch (ParseException e) {
}
} else {
format = new SimpleDateFormat("hh:mm", Locale.ENGLISH);
try {
date = format.parse(s);
} catch (ParseException e) {
}
}
Intent alarmIntent = new Intent(context, NotificationReciever.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
Log.d(Constants.LOG_TAG, calendar.getTime().toString());
if (Build.VERSION.SDK_INT < 19) {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
}
}
And this is my NotificationReciever class:
public class NotificationReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Constants.D) Log.d(Constants.LOG_TAG, "NOTIFICATION RECIEVER");
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.sc_logo_final)
.setContentTitle(context.getResources().getString(R.string.app_name))
.setContentText(context.getResources().getString(R.string.app_name));
Intent resultIntent = new Intent(context, NavigationDrawerActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(NavigationDrawerActivity.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(1, mBuilder.build());
}
}
In my AndroidManifest.xml,
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".AlarmReciever">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".NotificationReciever">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
First of all, this code is most likely setting up an alarm to happen at midnight of the current day, which is almost certainly in the past compared to the current time, which means you'll receive the alarm very quickly:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
According to the javadoc for setRepeating():
If the stated trigger time is in the past, the alarm will be triggered
immediately, with an alarm count depending on how far in the past the
trigger time is relative to the repeat interval.
Your Alarm does not repeat because you're using the flag INTERVAL_DAY, which only works with setInexactRepeating().
If you want to run something at midnight of the next day, you will need to add one day to the calendar. You might also consider setting the seconds field to 0 as well.
If you're registering the alarm every time the app starts, you'll keep getting that early alarm every time. Also according to the javadoc:
If there is already an alarm scheduled for the same IntentSender, it
will first be canceled.
The alarm is not repeating because you're passing an interval that is only valid for setInexactRepeating().