I am trying to achieve a task. Here is what's happening. I first save a value in the shared preference in a string from first activity and pass that value to this activity below. Then in my second activity, I call that value. Then I take the current time of the android and convert it to string.
=====================================================
#Lazy Ninja: UPDATED PLEASE CHECK: okay. I got the timings to match Finally! Now just one last thing, how do I keep running this "if statement" in the background so even if the app is closed, the system keeps checking for those two values?
=====================================================
UPDATED CODE:
Intent in = new Intent(Alarm.this, FajrAlarmRecieverActivity.class);
PendingIntent pi = PendingIntent.getActivity(Alarm.this, 2, in, PendingIntent.FLAG_CANCEL_CURRENT);
/*My Time from Shared Preference*/
//SharedPreferences prfs = getSharedPreferences("customeAlarmTimes", Context.MODE_PRIVATE);
//myTime = prfs.getString("Isha", "Isha");
String myTime = "11:15";
SimpleDateFormat formatter = new SimpleDateFormat("K:mm");
Date date = formatter.parse(myTime); // You will need try/catch around this
long millis = date.getTime();
/*My Time from Shared Preference*/
/*System Time*/
Date today = Calendar.getInstance().getTime();
String reportDate = new SimpleDateFormat("K:mm").format(today);
Date swag = formatter.parse(reportDate);
long currentTime= swag.getTime();
Log.d("SystemTime", reportDate);
Log.d("MyTime", myTime);
Log.d("SystemTime in Millis", currentTime+"");
Log.d("MyTime in Millis", millis+"");
if(millis == currentTime){
SendNotification();
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, AlarmManager.INTERVAL_DAY, pi);
}
else if (millis > currentTime){
Toast mtoast = Toast.makeText(getApplicationContext(), "FAJR TIME > CURRENT TIME", Toast.LENGTH_LONG);
mtoast.show();
}
else if (millis < currentTime){
Toast mtoast = Toast.makeText(getApplicationContext(), "FAJR TIME < CURRENT TIME", Toast.LENGTH_LONG);
mtoast.show();
}
}
}
Use repeating Alarm. It will handle the conditions for you
Try the following
Intent i = new Intent(getApplicationContext(), FajrAlarmRecieverActivity.class);
PendingIntent sender = PendingIntent.getActivity(Alarm.this, 0, i, 0);
// Get Time from your sharedpreferences
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour); // set Fajr hour
calendar.set(Calendar.MINUTE, minute); // set Fajr minute
calendar.set(Calendar.SECOND, 0); // set seconds ( well no need for seconds)
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
Dont forget to add FajrAlarmRecieverActivity in your manifest file.
After reading your comment just use set.
After the alarm fires, read from sharedPreferences and and set the alarm again.
EDIT
To get Current time
long currentTime= System.currentTimeMillis();
Get Time from your sharedPrefs, and convert it to milliseconds
if( sharedTimeInMillis < currentTime ){
// your good stuff
}
Convert your String time to milliseconds
myTime = prfs.getString("Isha", "Isha");
SimpleDateFormat formatter = new SimpleDateFormat("K:mm");
Date date = formatter.parse(myTime ); // You will need try/catch around this
long millis = date.getTime();
Related
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?
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();
}
}
First I want to change textview text everyday automatically. For example, first day the textview text is "First text", and second day text is "Second text" at 8 o'clock eveyday. And the text is permanent until next day 8 o'clock.
I try this code but my problem is that the code is not triggered if the user doesn't open this page at 8 o'clock. Texts are inside "mquote array"
SharedPreferences pref =getApplicationContext().getSharedPreferences("myPrefsKey",Context.MODE_PRIVATE) ;
dayCount = pref.getInt("dayCount", 0);
Calendar cal = Calendar.getInstance();
int hour=cal.get(Calendar.HOUR_OF_DAY);
int minute=cal.get(Calendar.MINUTE);
if ((hour==8 && minute==1 ))
updateQuote();
tvQuote.setText(mquote.getQuote(dayCount));
public void updateQuote()
{
if (dayCount==4)
dayCount=0;
dayCount++;
pref.edit().putInt("dayCount",dayCount).apply();
}
You need an AlarmManager implementation:
public class AlarmReceiver extends BroadcastReceiver {
// The app's AlarmManager, which provides access to the system alarm services.
private AlarmManager alarmMgr;
// The pending intent that is triggered when the alarm fires.
private PendingIntent alarmIntent;
public void setAlarm(Context context) {
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// set the Alarm's trigger time to 8:00 a.m.
calendar.set(Calendar.HOUR_OF_DAT, 9);
// Set the alarm to fire at approximately 8:30 a.m., according to the device's
// clock, and to repeat once a day.
alarmManager.setInexactRepeating(AlarmManager.RTC,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
}
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
alarm.setAlarm(context);
} else if(Objects.equals(intent, alarmIntent)) {
SharedPreferences pref = getApplicationContext().getSharedPreferences("key", Context.MODE_PRIVATE);
int dayCount = pref.getInt("dayCount", 0);
dayCount %= 4;
pref.edit().putInt("dayCount", ++daysCount).apply();
}
}
}
You should use timestamp to be able to compare two dates. try this code.
But the 1 day happens while user is using the app, it will not trigger. If you want to overcome this, then use AlarmManager to trigger an event every single day.
SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefsKey",Context.MODE_PRIVATE);
lastDay_ms= pref.getInt("time_ms", 0);
Calendar today = Calendar.getInstance();
long diff = today.getTimeInMillis() - lastDay_ms; //result in millis
final long ONE_DAY = 24*60*60*1000; //millis in a day
if (diff > ONE_DAY)
updateQuote();
Store milliseconds when you last updated preferences in your preferences:
SharedPreferences pref = getApplicationContext().getSharedPreferences("msKey", Context.MODE_PRIVATE);
msCount = pref.getInt("msCount", 0);
long milliseconds = System.currentTimeMillis();
long diff = milliseconds - msCount;
diff += (8 * 60 * 60 * 1000); // compensating difference for 8'O clock condition
int days = (int) Math.ceil(diff / 24 / 60 / 60 / 1000);
days %= 4; // Because you were resetting days count after 4 increments
updateQuote(days);
public void updateQuote(days) {
if(days == 0) {
pref.edit().putInt("msCount", milliseconds).apply();
}
}
I have searched a lot of places but couldnt find a clean sequential explanation of how to start a service (or if thats not possible then an activity) at a specific time daily using the AlarmManager??
I want to register several such alarms and triggering them should result in a service to be started. I'll be having a small piece of code in the service which can then execute and i can finish the service for good....
Calendar cal = Calendar.getInstance();
Calendar cur_cal = Calendar.getInstance();
cur_cal.setTimeInMillis(System.currentTimeMillis());
Date date = new Date(cur_cal.get(Calendar.YEAR), cur_cal.get(Calendar.MONTH), cur_cal.get(Calendar.DATE), 16, 45);
cal.setTime(date);
Intent intent = new Intent(ProfileList.this, ActivateOnTime.class);
intent.putExtra("profile_id", 2);
PendingIntent pintent = PendingIntent.getService(ProfileList.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pintent);
System.out.println("The alarm set!!");
i tried this code to activate the alarm at 4.45... but its not firing the service... do i have to keep the process running??
M i doing anything wrong???
One more thing, my service gets perfectly executed in case i use the following code:
long firstTime = SystemClock.elapsedRealtime();
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 30*1000,pintent);
HI friends,
After a lot of researching and with reference from "Pentium10"'s question on the same topic i managed to get it working. Though i still cant understand why the "date" concept and the Calendar(non GregorianCalendar) object which i have mentioned in the question are not working correctly.
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 18);
cal.set(Calendar.MINUTE, 32);
cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
Intent intent = new Intent(ProfileList.this, IntentBroadcastedReceiver.class);
PendingIntent pintent = PendingIntent.getService(ProfileList.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent);
//Create alarm manager
AlarmManager alarmMgr0 = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//Create pending intent & register it to your alarm notifier class
Intent intent0 = new Intent(this, AlarmReciever.class);
PendingIntent pendingIntent0 = PendingIntent.getBroadcast(this, 0, intent0, 0);
//set timer you want alarm to work (here I have set it to 7.20pm)
Intent intent0 = new Intent(this, OldEntryRemover.class);
Calendar timeOff9 = Calendar.getInstance();
timeOff9.set(Calendar.HOUR_OF_DAY, 19);
timeOff9.set(Calendar.MINUTE, 20);
timeOff9.set(Calendar.SECOND, 0);
//set that timer as a RTC Wakeup to alarm manager object
alarmMgr0.set(AlarmManager.RTC_WAKEUP, timeOff0.getTimeInMillis(), pendingIntent0);
Then in your AlarmReciever class which is a broadcastReciever, under onRecieve method put your logic. This will take care of what ever the logic you want to handle when the time comes to 7.20 pm.
If you need to set multiple alarms, create another Calendar instance & set time values appropriately. You also need to create another instance for pendingIntent otherwise timers will overlap. Then set it to same alarmManager with new timer & pendingIntent.
You can read document from https://developer.android.com/training/scheduling/alarms.html
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
The following code should work fine and it starts the service # 7:40 PM every day. Also, if device shuts down then all your alarms get cancelled.
Make sure to set up all the alarms after BOOT is completed.
Intent slIntent = new Intent(this, x.class);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 0);
PendingIntent slPendingIntent = PendingIntent.getService(this, 1, slIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, slPendingIntent);
I tried a lot To Start Service on Time So I Have one solution like
Calculate the difference between current time and selected time
from date picker "Return Long timeMileSec = Milliseconds" Difference
after this create a handler inside it and Sleep if "Milliseconds" seconds
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
CreateService();
getActivity().startService(intentServiceObj);
}
}, timeMileSec);
// Below is the service Methods.
private void CreateService() {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.DAY_OF_YEAR, year);
cal.set(Calendar.HOUR_OF_DAY, hourScreen);
cal.set(Calendar.MINUTE, minuteScreen);
// cal.setTimeInMillis(timeselectedmillisecond);
Intent intent = new Intent(getActivity(),
ServiceDailyLocationUpdate.class);
pintent = PendingIntent.getService(getActivity(), 0, intent, 0);
alarm = (AlarmManager) getActivity().getSystemService(
Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.HOUR, 86000 * 1000,
pintent);
}
// Return Differnce between two date
private long calculateDateDiffSecond(String firstDate, String secondDate) {
long numberOfDays = 0;
String dateStart = firstDate;
String dateStop = secondDate;
Date d1 = null;
Date d2 = null;
try {
d1 = sdfTime.parse(dateStart);
d2 = sdfTime.parse(dateStop);
// in milliseconds
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.print(diffDays + " days, ");
System.out.print("Hours::" + diffHours + " hours, ");
System.out.print("HoursMinute::" + diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");
numberOfDays = diffDays;
numberOfDays = diff;
} catch (Exception e) {
e.printStackTrace();
}
return numberOfDays;
}
codes above didn't work and below code worked for me.
month decreases 1.
and hours 0-11.
int day = ff.getGregorianDay() ;
int month = ff.getGregorianMonth() ;
int year = ff.getGregorianYear();
int hour = TimePicker1.getCurrentHour();
int minute = TimePicker1.getCurrentMinute();
Calendar cal_alarm = Calendar.getInstance();
cal_alarm.setTimeInMillis(System.currentTimeMillis() );
cal_alarm.set(Calendar.YEAR, year);
cal_alarm.set(Calendar.MONTH, month-1);
cal_alarm.set(Calendar.DAY_OF_MONTH, day);
cal_alarm.set(Calendar.AM_PM, Calendar.AM );
cal_alarm.set(Calendar.HOUR, hour);
if( hour >= 12){
cal_alarm.set(Calendar.AM_PM, Calendar.PM );
cal_alarm.set(Calendar.HOUR, hour-12);
}
cal_alarm.set(Calendar.MINUTE, minute );
cal_alarm.set(Calendar.SECOND, 0 );
Intent myIntent = new Intent(YadavariNewActivity.this, Alarm_Sag.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(YadavariNewActivity.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set( AlarmManager.RTC_WAKEUP, cal_alarm.getTimeInMillis(), pendingIntent);
I am trying to get a notification to pop up based on the user date and time they put in. Here is my code for getting the time values
// String GetRawDate Gets The User Value For Date//
String getRawDate = date.getText().toString();
// String SplitDate Splits The Date Into Three Separate Ints//
String[] splitDate = getRawDate.split("/");
// Int GetMonth Gets The Value Of The Month//
int getMonth = Integer.parseInt(splitDate[0]);
// Int GetDay Gets The Value Of The Day//
int getDay = Integer.parseInt(splitDate[1]);
// Int GetYear Gets The Value Of The Year//
int getYear = Integer.parseInt(splitDate[2]);
// Get Military Start Time//
String test = military_start_time;
// Split It//
String[] splitStartTime = test.split(":");
// Get Hour In Integer Form
int getHour = Integer.parseInt(splitStartTime[0]);
// Get Minute In Integer Form//
int getMinute = Integer.parseInt(splitStartTime[1]);
From here I add these values to calendar
// Gets Calendar Instance//
Calendar calendar = Calendar.getInstance();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, getMonth);
cal.set(Calendar.YEAR, getYear);
cal.set(Calendar.DAY_OF_MONTH, getDay);
cal.set(Calendar.HOUR_OF_DAY, getHour);
cal.set(Calendar.MINUTE, getMinute);
Then I set my alarm
// Intent To Start Notification After X Seconds//
Intent alertIntent = new Intent(this, ReminderService.class);
alertIntent.putExtra("name", name.getText().toString());
alertIntent.putExtra("time", starttime.getText().toString());
// Defines Alarm Manager//
AlarmManager alarmManager = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
// Sets Alarm Manager//
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), PendingIntent.getBroadcast(this, 1,
alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
// Starts Activity ListView//
Intent b = new Intent(this, Reminders.class);
startActivity(b);
overridePendingTransition(R.anim.slid_in, R.anim.slid_out);
Say the user has the date of 6/4/15 and the Time 22:10 I want the notification to show up on this time. For some reason it shows up about 5 seconds after the code is run through. Anybody know what I am doing wrong with the alarm?
try using
alarmManager.setExact(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), PendingIntent.getBroadcast(this, 1,
alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
P.S: Needs min API:19