I have a boot reciever in my homework planner application to re-set all of the alarms that are created to remind the user of their homework being due in. Everytime my phone boots, I get "Homework planner has stopped", and I cannot figure out why. And I cannot use LogCat as it is not connecting on startup (?).
This is my code in the boot reciever.
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// RE-SET ALL ALARMS FROM THE DATABASE WHEN PHONE IS TURNED ON
HomeworkDatabase db = new HomeworkDatabase(context);
db.open();
ArrayList<HomeworkItem> hwks = db.getHomeworks();
db.close();
int reminders = 0;
for (int e = 0; e < hwks.size(); e++) {
HomeworkItem current = hwks.get(e);
{
Calendar c = Calendar.getInstance();
c.set(current.year, current.month, current.day, 0, 0);
long alarmTime = c.getTimeInMillis();
Intent i = new Intent(HomeworkList.getAppContext(),
RegularAlarm.class);
i.putExtra("title", current.title);
i.putExtra("id", current.id);
PendingIntent pi = PendingIntent.getBroadcast(
HomeworkList.getAppContext(), (int) current.id, i, 0);
AlarmManager mAlarm = (AlarmManager) context
.getApplicationContext().getSystemService(
Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
reminders++;
}
if (current.oneDayReminder == true) {
Calendar c = Calendar.getInstance();
c.set(current.year, current.month, current.day, 0, 0);
c.roll(Calendar.DAY_OF_MONTH, -1);
long alarmTime = c.getTimeInMillis();
Intent i = new Intent(HomeworkList.getAppContext(),
OneDayAlarm.class);
i.putExtra("title", current.title);
i.putExtra("id", current.id);
PendingIntent pi = PendingIntent.getBroadcast(
HomeworkList.getAppContext(), (int) current.id, i, 0);
AlarmManager mAlarm = (AlarmManager) context
.getApplicationContext().getSystemService(
Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
reminders++;
}
if (current.twoDayReminder == true) {
Calendar c = Calendar.getInstance();
c.set(current.year, current.month, current.day, 0, 0);
c.roll(Calendar.DAY_OF_MONTH, -2);
long alarmTime = c.getTimeInMillis();
Intent i = new Intent(HomeworkList.getAppContext(),
TwoDaysAlarm.class);
i.putExtra("title", current.title);
i.putExtra("id", current.id);
PendingIntent pi = PendingIntent.getBroadcast(
HomeworkList.getAppContext(), (int) current.id, i, 0);
AlarmManager mAlarm = (AlarmManager) context
.getApplicationContext().getSystemService(
Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
reminders++;
}
}
Log.d("hwk","BOOT COMPLETE: " + reminders + " alarms created");
Toast.makeText(context, reminders + " alarms created at boot", Toast.LENGTH_LONG);
}
}
Sorry for the long code snippet, but I have no idea what the problem is.
Thanks
EDIT: The source of the error is when creating the intent and getting the context from the for the PendingIntent.
Intent i = new Intent(HomeworkList.getAppContext(), RegularAlarm.class);
This line is causing a null pointer exception. Any idea why?
Related
I was using setRepeating() function to schedule events in my Application. According to Android documentation setRepeating() is not exact from API level 19+.In the app, when it is time to alarm (every day at 23:59) broadcast receiver is called. However, this broadcast receiver is being called too early(ex: sometimes it is being called right after I set the alarm although there are more than 10 hours until 23:00)
Here is my code:
set Alarm function:
public void setEmaResetAlarm(Context context) {
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManagerMorning = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
intentResetNight = new Intent(context, EMAAlarmRcvr.class);
intentResetNight.putExtra("ema_reset_night", true); //time to reset EMA to 0
intentResetMorning = new Intent(context, EMAAlarmRcvr.class);
intentResetMorning.putExtra("ema_reset_morning", true); //time to reset EMA to 0
intentRemove = new Intent(context, EmaDismissReceiver.class);
intentRemove.putExtra("ema_pop_up_remove", true); // time to remove EMA pop up
pendingIntentResetNight = PendingIntent.getBroadcast(context, 10, intentResetNight, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntentResetMorning = PendingIntent.getBroadcast(context, 8, intentResetMorning, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntentRemove = PendingIntent.getBroadcast(context, 11, intentRemove, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmManager == null || alarmManagerMorning == null)
return;
emaTimeSubscription = context.getSharedPreferences("SubscriptionCheck", Context.MODE_PRIVATE);
int hour1 = Integer.parseInt(emaTimeSubscription.getString("hours1", null));
int hour2 = Integer.parseInt(emaTimeSubscription.getString("hours2", null));
int hour3 = Integer.parseInt(emaTimeSubscription.getString("hours3", null));
Calendar firingCallReset = Calendar.getInstance();
firingCallReset.set(Calendar.HOUR_OF_DAY, 23); // at 11:59pm
firingCallReset.set(Calendar.MINUTE, 59); // Particular minute
firingCallReset.set(Calendar.SECOND, 0); // particular second
firingCallReset.set(Calendar.MILLISECOND, 0); // particular second
//alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCallReset.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentResetNight);
Calendar firingCalResetMorning = Calendar.getInstance();
firingCalResetMorning.set(Calendar.HOUR_OF_DAY, 9); // at 9:30am
firingCalResetMorning.set(Calendar.MINUTE, 30); // Particular minute
firingCalResetMorning.set(Calendar.SECOND, 0); // particular second
firingCalResetMorning.set(Calendar.MILLISECOND, 0); // particular second
//alarmManagerMorning.setRepeating(AlarmManager.RTC_WAKEUP, firingCalResetMorning.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentResetMorning);
//remove EMA pop up
Calendar firingCalRemove11 = Calendar.getInstance();
firingCalRemove11.set(Calendar.HOUR_OF_DAY, hour1 + 1); // at 11:01am
firingCalRemove11.set(Calendar.MINUTE, 1); // Particular minute
firingCalRemove11.set(Calendar.SECOND, 0); // particular second
firingCalRemove11.set(Calendar.MILLISECOND, 0); // particular second
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove11.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
Calendar firingCalRemove15 = Calendar.getInstance();
firingCalRemove15.set(Calendar.HOUR_OF_DAY, hour2 + 1); // at 3:01pm
firingCalRemove15.set(Calendar.MINUTE, 1); // Particular minute
firingCalRemove15.set(Calendar.SECOND, 0); // particular second
firingCalRemove15.set(Calendar.MILLISECOND, 0); // particular second
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove15.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
Calendar firingCalRemove19 = Calendar.getInstance();
firingCalRemove19.set(Calendar.HOUR_OF_DAY, hour3 + 1); // at 7:01pm
firingCalRemove19.set(Calendar.MINUTE, 1); // Particular minute
firingCalRemove19.set(Calendar.SECOND, 0); // particular second
firingCalRemove19.set(Calendar.MILLISECOND, 0); // particular second
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove19.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
}
BroadcastReceiver to be called:
public class EMAAlarmRcvr extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences loginPrefs = context.getSharedPreferences("UserLogin", MODE_PRIVATE);
SharedPreferences configPrefs = context.getSharedPreferences("Rewards", MODE_PRIVATE);
//For resetting ema prefr (11:59 PM ) and (9:30 AM )
if (intent.getBooleanExtra("ema_reset_night", false) || intent.getBooleanExtra("ema_reset_morning", false)) {
SharedPreferences.Editor ema_editor = configPrefs.edit();
SharedPreferences.Editor hrm_editor = configPrefs.edit();
Log.e("TAG", "onReceive: TaskManager" );
hrm_editor.putBoolean("hrm_completed", false);
hrm_editor.apply();
ema_editor.putBoolean("ema1_answered", false);
ema_editor.putBoolean("ema2_answered", false);
ema_editor.putBoolean("ema3_answered", false);
ema_editor.putInt("ema_answered_count", 0);
ema_editor.apply();
SharedPreferences.Editor loginEditor = loginPrefs.edit();
loginEditor.putBoolean("ema_btn_make_visible", false);
loginEditor.apply();
}
}
}
Before setting a new alarm you should cancel any previous alarms as:
alarmManager.cancel(pendingIntent);
Also, use same pending intent that you use to create a new alarm to cancel old set one because is used as unique identifier, so:
// cancel old alarm
alarmManager.cancel(pendingIntentRemove);
// then create new one
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove11.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
You get called at random times because is created a new alarm
I've created a notification and it's just doesnt show up.
My code in the main activity: `boolean alarm = (PendingIntent.getBroadcast(this, 0, new Intent("ALARM"), PendingIntent.FLAG_NO_CREATE) == null);
if(alarm){
Intent itAlarm = new Intent("ALARM");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,itAlarm,0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 3);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
AlarmManager alarme = (AlarmManager) getSystemService(ALARM_SERVICE);
alarme.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),60000, pendingIntent);
}
my code in the Broadcast Reciver:
public class BroadcastManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
String yourDate = "04/05/2016";
String yourHour = "13:07:00";
Date d = new Date();
DateFormat date = new SimpleDateFormat("dd/MM/yyyy");
DateFormat hour = new SimpleDateFormat("HH:mm:ss");
if (date.equals(yourDate) && hour.equals(yourHour)){
Intent it = new Intent(context, MainActivity.class);
createNotification(context, it, "new mensage", "body!", "this is a mensage");
}
}catch (Exception e){
Log.i("date","error == "+e.getMessage());
}
}
public void createNotification(Context context, Intent intent, CharSequence ticker, CharSequence title, CharSequence descricao){
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent p = PendingIntent.getActivity(context, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setTicker(ticker);
builder.setContentTitle(title);
builder.setContentText(descricao);
builder.setSmallIcon(R.drawable.web_hi_res_512);
builder.setContentIntent(p);
Notification n = builder.build();
//create the notification
n.vibrate = new long[]{150, 300, 150, 400};
n.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(R.drawable.web_hi_res_512, n);
//create a vibration
try{
Uri som = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone toque = RingtoneManager.getRingtone(context, som);
toque.play();
}
catch(Exception e){}
}
}
Above code will start alarm service on every 3 seconds and repeat on every 1 minute. If you want to generate notification on specific time then, You have to add,
calendar.add(Calendar.HOUR, 13);
calendar.add(Calendar.MINUTES, 07);
calendar.add(Calendar.SECONDS, 00);
and remove this line,
calendar.add(Calendar.SECOND, 3);
I hope it may work for you.
I try to have a notification repeated daily (For debugging I set it to every 10s). However, it is firing the notification only the first time, then nothing happens.
Here is the code where the alarm is set:
Intent myIntent = new Intent(ctx , NotifyService.class);
AlarmManager alarmManager =(AlarmManager)ctx.getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(ctx, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1000 * 10, pendingIntent);
and here is the service:
public class NotifyService extends Service {
public NotifyService() {
}
#Override
public void onCreate(){
//Create and Emit the notification.
}
I have tried different flags in getService(ctx, int, Intent, flags), to use setInexactRepeating and to set a new alarm after every call to the NotifyService.
Use the method below to repeating the alarm once in a day and you have to register broadcast receiver instead of service with AlarmManager so that you can start your service from the receiver and that is recommended.
Find the official doc.
private final static String ACTION = "ACTION_ALARM";
public static void setWakeUpAction(Context context, String hourSet, String minuteSet, String periodSet, int requestCode, String currentAction) {
try {
String mHour = hourSet;
String mMin = minuteSet;
String[] parsedFormat = null;
Calendar calendar = Calendar.getInstance();
SimpleDateFormat displayFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat parseFormat = new SimpleDateFormat("hh:mm a");
Date date = parseFormat.parse(mHour + ":" + mMin + " " + periodSet);
parsedFormat = displayFormat.format(date).split(":");
mHour = parsedFormat[0];
mMin = parsedFormat[1];
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(mHour));
calendar.set(Calendar.MINUTE, Integer.parseInt(mMin));
calendar.set(Calendar.SECOND, 00);
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra(ACTION, currentAction);
myIntent.putExtra("Time", new String[]{mHour, mMin, periodSet});
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
} catch (ParseException e) {
e.printStackTrace();
}
}
BroadCastReceiver
public class MyReceiver extends BroadcastReceiver {
private final String ACTION = "ACTION_ALARM";
private String ACTION_ONE = "ALARM_REPEAT";
#Override
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getStringExtra(ACTION);
new ShowToast(context, action);
if (action.length() > 1) {
if (action.equals(ACTION_ONE) ) {
String time[] = intent.getStringArrayExtra("Time");
startService(context, action);
}
}
} catch (Exception e) {
}
}
public void startService(Context context, String action) {
Intent service1 = new Intent(context, NotifyService.class);
service1.putExtra(ACTION, action);
context.startService(service1);
}
}
Manifest
<service
android:name=".NotifyService"
android:enabled="true" />
<receiver android:name=".MyReceiver" />
Usage
setWakeUpAction(context, "11", "00","AM","0", "ALARM_REPEAT");
Use a PendingIntent for a BroadcastReceiver rather than a Service, that is the recommended (and documented) practice. Plus, if you are using "wakeup" alarms, you'll need to use a BroadcastReceiver otherwise the system will not guarantee that it stays awake long enough for your Service to actually execute and receive the Intent. See this article for more details: http://po.st/7UpipA
Try this,
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// setRepeating() lets you specify a precise custom interval--in this case,
// 10 seconds.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 10, alarmIntent);
Refer : http://developer.android.com/training/scheduling/alarms.html
I am having some problem when trying to prompt notification based on the timing set by Alarm Manager in Android.
So what I am trying to do is a budget setting application. If the monthly expenses exceed the budget, it will prompt notification. In order to keep the question short, I will just post the part where I interact with Alarm Manager:
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context, BudgetAlarm.class);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
&& percentage >= 90) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
notificationCount = notificationCount + 1;
// Set request flag to 1 so that the same pending intent in broadcastReceiver
notificationIntent.putExtra("NotifyCount", notificationCount);
pi = PendingIntent.getBroadcast(context, 1,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
What I am trying to do here is to check if the expenses exceed the budget. And inside the BudgetAlarm class, I am prompting the notification:
private NotificationManager mNotificationManager;
private Notification notification;
#Override
public void onReceive(Context context, Intent intent) {
mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(context, 1,
new Intent(), 0);
notification = new Notification(R.drawable.ic_launcher, "Notification",
System.currentTimeMillis());
notification.setLatestEventInfo(context, "Budget Reminder",
"Your monthly expenses nearly exceed the budget!",
contentIntent);
mNotificationManager.notify(
Integer.parseInt(intent.getExtras().get("NotifyCount")
.toString()), notification);
}
My problem now is it does set and trigger the alarm manager every day. But let's say today I did not run the apps, it does prompt me a notification to notify me. But after a while, I launch the app, then it prompt me again.
I wonder is there any way to set the notification to just notify once per day regardless of how many times I launch the apps. I was actually thinking of something like cookies or shared preference.
Thanks in advance.
EDIT
public class BudgetAlarm extends BroadcastReceiver {
private NotificationManager mNotificationManager;
private Notification notification;
#Override
public void onReceive(Context context, Intent intent) {
saveDay(context);
if (sameDay(context) == false) {
mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(context, 1,
new Intent(), 0);
notification = new Notification(R.drawable.ic_launcher,
"Notification", System.currentTimeMillis());
notification.setLatestEventInfo(context, "Budget Reminder",
"Your monthly expenses nearly exceed the budget!",
contentIntent);
mNotificationManager.notify(
Integer.parseInt(intent.getExtras().get("NotifyCount")
.toString()), notification);
saveDay(context);
}
}
private boolean sameDay(Context context) {
boolean isSameDay = false;
SharedPreferences pref = context.getSharedPreferences("PrefKey",
Context.MODE_PRIVATE);
Calendar cal = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
Date today = cal.getTime();
String day = format.format(today);
String savedDate = pref.getString("SaveDateKey", "NONE");
if (savedDate.equals(day)) {
isSameDay = true;
} else {
isSameDay = false;
}
return isSameDay;
}
private void saveDay(Context context) {
SharedPreferences pref = context.getSharedPreferences("PrefKey",
Context.MODE_PRIVATE);
Editor editor = pref.edit();
Calendar cal = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
Date today = cal.getTime();
String day = format.format(today);
editor.putString("SaveDateKey", day);
editor.commit();
}
}
I think You are on the right way with shared preferences. This could be a scenario in Your app: make a method to know if the same day is equal, if not, save the date when You start the app:
private boolean sameDay(){
boolean isSameDay = false;
SharedPreferences pref = getApplicationContext().getSharedPreferences(YOUR_PREF_KEY, Context.MODE_PRIVAT);
Calendar cal = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
Date today = cal.getTime();
String day = format.format(today);
String savedDate = pref.getString(YOUR_SAVED_DATE_KEY,"NONE");
if(savedDate.equals(day){
isSameDay=true;
}else{
isSameDay=false;
}
return isSameDay;
}
And to save the current day:
private void saveDay(){
SharedPreferences pref = getApplicationContext().getSharedPreferences(YOUR_PREF_KEY, Context.MODE_PRIVAT);
Editor editor = pref.edit();
Calendar cal = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
Date today = cal.getTime();
String day = format.format(today);
editor.putString(YOUR_SAVED_DATE_KEY,day);
editor.commit();
}
And then You just handling this inside Your onReceive():
if(sameDay==true){
//donĀ“t notify
}else{
//notify and save the day
saveDay();
}
the notifications of my app open without a logical sense than the code that I wrote. I should receive a notification every day at the same time but if I open the app I get the same notification. This is the code in MainActivity:
public void setRepeatingAlarm() {
Intent intent = new Intent(this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 13);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),24*60*60*1000,pendingIntent);
}
And this is MyAlarmService:
public class MyAlarmService extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "Locali Torino";
CharSequence message = "Visita le serate!";
Intent action = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
action, 0);
Notification notif = new Notification(R.drawable.disco,
"Visita le serate!", System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(0, notif);
}
}
Why I get notifications when I open the app or at least not only at the set time?
EDIT
MyAlarmService:
public class MyAlarmService extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "Locali Torino";
CharSequence message = "Visita le serate!";
Intent action = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
action, 0);
Notification notif = new Notification(R.drawable.disco,
"Visita le serate!", System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(0, notif);
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mPref.edit();
long time = System.currentTimeMillis();
mEditor.putLong("UPDATE_TIME", time);
mEditor.commit();
}And this is MainActivity:
public void setRepeatingAlarm() {
Intent intent = new Intent(this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
long startAt;
long period;
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
long dif = System.currentTimeMillis() - mPref.getLong("UPDATE_TIME", 0);
if (dif >= UPDATE_PERIOD) {
startAt = 0;
period = UPDATE_PERIOD;
} else {
startAt = dif;
period = dif;
}
am.setRepeating(AlarmManager.RTC_WAKEUP, startAt, period,pendingIntent);
}
The service runs when you register it, so what you need to do is pass a boolean value with the intent when registering the service to prevent it from running when the application runs, but to run periodically thereafter.
In your activity add:
intent.putExtra("run", false);
Then in MyAlarmService:
private boolean run = true;
// ...
action.getBooleanExtra("run", run);
if(run) {
// notifications code
} else {
run = true;
}
Actually it works exactly as code is written. The cause of that behavior is your startAt parameter in setRepeating method.
am.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
24*60*60*1000,
pendingIntent);
calendar.getTimeInMillis() time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type).
For example :
//send first alarm after 1 second and repeat it every 24 hours
am.setRepeating(AlarmManager.RTC_WAKEUP,
1000,
24*60*60*1000,
pendingIntent);
//send first alarm after 10 second and repeat it every 24 hours
am.setRepeating(AlarmManager.RTC_WAKEUP,
10000,
24*60*60*1000,
pendingIntent);
UPDATE :
You need to save your last update time :
public class MyAlarmService extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
//send alarm here
//...
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mPref.edit();
mEditor.putLong("UPDATE_TIME", time);
mEditor.commit();
}
}
Then you can make your setRepeatingAlarm method like this :
public void setRepeatingAlarm() {
Intent intent = new Intent(this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
long startAt;
long period;
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
long dif = System.currentTimeMillis() - mPref.getLong("UPDATE_TIME", 0);
if (dif >= UPDATE_PERIOD) {
startAt = 0;
period = UPDATE_PERIOD;
} else {
startAt = dif;
period = dif;
}
am.setRepeating(
AlarmManager.RTC_WAKEUP,
startAt,
period,
pendingIntent);
}