Refresh date in Broadcast Receiver Android - android

I have a broadcast receiver class which I call at the beginning of a new day.
Here is the broadcast receiver onReceive method.
#Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent(NEW_DAY_FROM_RECEIVER));
Log.d(TAG, "Old day passed, new day in!");
DateFormat dateFormat = new SimpleDateFormat("EEE, MMM d");
Date yesterdaysDate = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
String yesterdaysDateString = dateFormat.format(yesterdaysDate);
// Saving the value
DailyPointsItem yesterdayPointsItem = new DailyPointsItem(yesterdaysDateString, String.valueOf(pointsForToday), notEatenItemsArrayList, DailyPointsItem.DAILY_FOOD_POINT);
Log.d(TAG,"Points: " + yesterdayPointsItem.getTitle() + " : " + yesterdayPointsItem.getDescription());
addDailyPointsItem(context, yesterdayPointsItem);
}
public static void addDailyPointsItem(Context context, DailyPointsItem yesterdayPointsItem) {
ArrayList<DailyPointsItem> dailyPointsDataList = SharedPreferencesManager.getDailyPointsItemsArrayList(context);
dailyPointsDataList.add(0, yesterdayPointsItem);
if(dailyPointsDataList.size()==8){
dailyPointsDataList.remove(7);
}
final SharedPreferences.Editor editor = getSharedPreferences(context).edit();
Gson gson = new Gson();
String jsonDailyPointsArray = gson.toJson(dailyPointsDataList);
editor.putString(JSON_STRING_POINTS_ARRAY, jsonDailyPointsArray);
editor.apply();
}
Here I store the string yesterdaysDateString (which is the string of the previous day that just passed), and display this data some place else.
This broadcast receiver I call at the begining of each day using an AlarmManager, called in my Main Activity when the app starts, like this:
Intent intent = new Intent(this, NewDayReceiver.class);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
if (!calendar.before(Calendar.getInstance())) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent); //Repeat every 24 hours
Log.d(TAG, "New day alarm set for:" + calendar.getTime() + " and will repeat every day");
}
Now this works fine, and each day that comes in the date is stored in the string. However the date is only correctly saved if the app is opened each day. If the app isn't opened each day, the AlarmManager works and the broadcast receiver is called, however the date that is saved is the date of the last day the app was open. If for example the app was opened Sun, Mar 25, and not opened for 3 days. then the three dates that are stored are Sun, Mar 25. Why is the Broadcast receiver not saving the current date.
EDITED: It works when the phone is used, but if the phone isn't used and left idle, it doesn't save the correct date. Why would this be so?

Related

AlarmManager shifts time by 12 hours

I'm trying to create periodical notifications.
So, I created a function to reschedule new notification time:
private void rescheduleNotification(Context context) {
long nextNotifTime = System.currentTimeMillis();
// Schedule next notification in 15 minutes
nextNotifTime += 15 * 60 * 1000;
Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(nextNotifTime);
// It's an old version with the same result
//calendar.add(Calendar.MINUTE, 15);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy HH:mm:ss", Locale.ENGLISH);
this.logEvent(" Next notification time is: " + sdf.format(calendar.getTimeInMillis()));
Intent intent = new Intent(context, WordsBcReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager manager = (AlarmManager)context.getSystemService(ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= 23) {
manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextNotifTime, pendingIntent);
} else {
manager.set(AlarmManager.RTC_WAKEUP, nextNotifTime, pendingIntent);
}
this.logEvent(" Set next notification time: " + sdf.format(nextNotifTime));
}
Sometimes it runs correctly, but sometimes notification time shifts by exactly 12 hours.
I added special function to log all time manipulations, so the log contains:
29/12/17 11:30:36: Next notification time is: 29/12/17 12:00:36
29/12/17 11:30:36: Set next notification time: 29/12/17 12:00:36
seems OK, but adb shell dumpsys alarm says:
type=0 whenElapsed=+11h34m13s906ms when=2017-12-30 00:00:36
I tried to use Calendar (I to exclude some periods later), but result was the same.
Can't find the problem...

Alarm manager not pushing data in server periodically for nougat

i am using AlarmManager to call the PendingIntent. which triggers the WakefulBroadcastReceiver to push the data in server periodically. but for nougat, its not pushing in the periodic time. and also draining battery too much.
my code is here->
public static void startSyncAlarm(String enteredTime) {
// Construct an intent that will execute the AlarmReceiver
Intent intent = new Intent(context, SyncDbToServerAlarmReceiver.class);
intent.putExtra(Constants.ENTERED_TIME, enteredTime);
// Create a PendingIntent to be triggered when the alarm goes off
final PendingIntent pIntent = PendingIntent.getBroadcast(context, SyncDbToServerAlarmReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// alarm needs to be set after 5 minutes of entered time
// convert entered time to milliseconds
// create Date object using string time format with using Simple date format
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss aa");
try {
Date enteredDate = format.parse(enteredTime);
long enteredTimeInMillis = enteredDate.getTime();
long intervalMillis = 30 * 60 * 1000; // 30 minutes gap
long triggerAtMillis = enteredTimeInMillis + intervalMillis;
Log.d(TAG, "start alarm, enteredTimeMillis = " + enteredTimeInMillis + "\ntriggerAtMillis = " + triggerAtMillis);
//long firstMillis = System.currentTimeMillis(); // alarm is set right away
syncDbAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Setup periodic alarm every 5 minutes
syncDbAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtMillis/*firstMillis*/,
intervalMillis, pIntent);
} catch (ParseException e) {
e.printStackTrace();
}
}

android: am pm format of alarm

I am using the alarmmanger class set method for setting the alarm. i
takes the input from user through timepicker dialog for setting the
alarm.alarm work fine when i set specific hour and minutes but
application is not following the am/pm logic. mean if i set the alarm
10:31 am while in system time is 10:30 pm then alarm invoke at 10:31 pm not at 10:30 am.anyone tell me whats the reason?
Calendar time = Calendar.getInstance();
time.set(Calendar.HOUR, hourOfDay);
time.set(Calendar.MINUTE, minute);
time.set(Calendar.SECOND, 5);
//time.set(Calendar.AM_PM);
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(), pendingIntent);
you need to set the time with the time format using SimpleDateFormat or DateFormat class which will give the date based on the date-time string and get that value using getTime and set into the alarm in set method.
Or you can do another way get the alarm time and check whether it's am or pm and set this attribute into the calendar object with time and date and get millisecond value from the calendar set into the alarm.set() method.
Hope you get some idea/suggestion
Edit
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a"); // this is you format
Date d = sdf.parse("19/12/2011 03:47:00 pm"); // this string getting you from your timepicker
Intent myIntent = new Intent(youractivity.this, AlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(youractivity.this, 0, myIntent, PendingIntent.FLAG_ONE_SHOT);
am.set(AlarmManager.RTC_WAKEUP, d.getTime(), pendingIntent);
Note: you need to put into the try and catch block parse part it may be cause error during parsing time
I used this method in setting alarm:
/**
* Set the Alarm
*
* #param context the activity context
* #param id the alarm ID for this app
* #param hour the alarm hour
* #param minute the alarm minute
* #param timeZone the timezone am = Calendar.AM or pm = Calendar.PM
*/
public static void setAlarm(Context context, int id, int hour, int minute, int timeZone) {
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.AM_PM, timeZone);
Intent intent = new Intent(context, PopupActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, id, intent, 0);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pIntent);
}
For the timezone parameter use either am = Calendar.AM or pm = Calendar.PM
Change the below line:
time.set(Calendar.HOUR, hourOfDay);
to
time.set(Calendar.HOUR_OF_DAY, hourOfDay);

AlarmManager launching multiple times

I am using this code to create an Alarm in a activity that can be launched by the user.
The Alarm sends an intent that launches a broadcast reciever and then a service.
private void setGameAlerts(){
//Setting alarm to fire off NEW_GAME intent every 24 hours.
String alarm = Context.ALARM_SERVICE;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
AlarmManager am = (AlarmManager)getActivity().getSystemService(alarm);
Intent intent = new Intent("NEW_ITEM");
PendingIntent sender = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, sender);
Log.e("RELEASE LIST", "ALARM Set For 1 day from " + calendar.getTimeInMillis());
For some reason EVERYTIME the activity is launched it Automatically sends this intent and the service is launched. is there something wrong with my code that is causing this to happen other than the alarm going off everyday at 8 oclock?
It looks to me like you're setting it for 8am TODAY, not 8am tomorrow. For example, if I run this code:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
Log.i("Test", "Current time: " + System.currentTimeMillis() );
Log.i("Test", "Calendar time: " + calendar.getTimeInMillis() );
calendar.add(Calendar.DATE, 1);
Log.i("Test", "Calendar time with a day added: " + calendar.getTimeInMillis() );
I get the result:
10-06 23:26:50.050: INFO/Test(8890): Current time: 1317968810056
10-06 23:26:50.050: INFO/Test(8890): Calendar time: 1317913200000
10-06 23:26:50.050: INFO/Test(8890): Calendar time with a day added: 1317999600000
The calendar time is a number less than the current time, so therefore that calendar entry is in the past. It might make some sense that Android would immediately send the intent for an event that has past. If you add a day to it, or specify a date in your Calendar object, it should work.
Note that this numerical dates are simply the standard Unix time with milliseconds added on. If you drop the last three digits and put the number into a Unix time converter, you'll be able to check that the numbers you're working with make sense. Eg: use 1317999600 with the Unix time converter and you'll get 10am EST, which is 8am PST (my time zone).
I hope that helps!

AlarmManager setting more than once?

I am using this code to set a Alarm everyday for 8 oclock the next day.
I am setting this alarm in an activity that can be opened based upon the user.
//Setting alarm to fire off NEW_GAME intent every 24 hours.
String alarm = Context.ALARM_SERVICE;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
Log.i("Test", "Current time: " + System.currentTimeMillis() );
Log.i("Test", "Calendar time: " + calendar.getTimeInMillis() );
int currentDate = calendar.get(Calendar.DATE);
calendar.set(Calendar.DATE, currentDate+1);
Log.i("Test", "Calendar time with a day added: " + calendar.getTimeInMillis() );
AlarmManager am = (AlarmManager)getActivity().getSystemService(alarm);
Intent intent = new Intent("NEW_ITEM");
PendingIntent sender = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, sender);
My only question is..Lets say at 10:00 o clock today am. i open the activity that alarm is set for tomorrow..Lets say i open the activity again at 12:00 am mid-night, will the alarm set earlier that day be overr written by the current alarm being set?
If you use the same request number (second parameter) while creating the PendingIntent object
PendingIntent sender = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
then it will overwrite the current PendingIntent and hence will replace the current Alarm.
It will also depend on what you pass as the last parameter to it. Possible values given in the constants section here.

Categories

Resources