AlarmManager - How to set a Notification to appear annually - android

I want an notification to appear each year depending on the date entered (Birthday). I have everything else working bar how to set a notification annually. As you can see below I have changed the code to say "HERE" where the intervals go. There are intervals for days and I know I could multiply that by 365. But what happens if its a leap year..
int REQUEST_CODE = 7;
Intent intent = new Intent(Activity2.this, Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Activity2.this, REQUEST_CODE, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(am.RTC_WAKEUP, System.currentTimeMillis(), HERE, pendingIntent);

You could replace 'HERE' with a method that determines if the following February from today is in a leap year, and then returns the value 365 or 366 days (in the form of milliseconds mind you) based on those checks.
private long millisUntilNextYear(){
//Set days in a year for Leap and Regular
final int daysInLeapYear = 366;
final int daysInYear = 365;
//Get calendar instance
GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
//Get this year and next year
int thisYear = cal.get(GregorianCalendar.YEAR);
int nextYear = thisYear + 1;
//Get today's month
int thisMonth = cal.get(GregorianCalendar.MONTH);
//Get today's date
int dayOfMonth = cal.get(GregorianCalendar.DAY_OF_MONTH);
//Is today before February? If so then the following February is in THIS year
if (thisMonth < GregorianCalendar.FEBRUARY){
//Check if THIS year is leapYear, and return correct days (converted to millis)
return cal.isLeapYear(thisYear) ? daysToMillis(daysInLeapYear) : daysToMillis(daysInYear);
}
//Is today after February? If so then the following February is NEXT year
else if (thisMonth > GregorianCalendar.FEBRUARY) {
//Check if NEXT year is leapYear, and return correct days (converted to millis)
return cal.isLeapYear(nextYear) ? daysToMillis(daysInLeapYear) : daysToMillis(daysInYear);
}
//Then today must be February.
else {
//Special case: today is February 29
if (dayOfMonth == 29){
return daysToMillis(daysInYear);
} else {
//Check if THIS year is leapYear, and return correct days (converted to millis)
return cal.isLeapYear(thisYear) ? daysToMillis(daysInLeapYear) : daysToMillis(daysInYear);
}
}
}

1) save dates in MM/DD/YY formats.
2) read these dates when you open your app(or at different times)
3) set alerts for single day/today it self.
Plus you can also show birthdays coming in next week/month etc.

Related

How to get the number of days in a week given a string date

I have A string which is
String dateOfOrder = "01/06/2019";
I would like to get the number of days in Week 1 as June first week only have 1 day.
May i know how do i approach on receviing number of days in Week X ?
Like In June 2019
Week 1 : Have 1 day Week 2 - 5 : have 7 days Week 6 : Have 1 day
EDIT
I'm thinking of this approach of getting number of days in a week whereby I have a couple of String arrayList. For example on my given date above, if Week 1 Have Saturday. Week 1 Array List will add saturday in it and .size().
If Week 2 have Sunday to Saturday, it will add all the dates in the Week 2 Array List and .size() to get the number of days in the ArrayList.
Lastly, The last week of June which is Week 6 will have Sunday only and it will add into Week 6 ArrayList and have value of Sunday only and .size() to get 1.
I'm wondering if its the best approach and I'm not sure if i can get the correct days in the week.
Parse the string as date using SimpleDateFormatter. Your parsing pattern could be dd/MM/YYYY.
DateFormat df = new SimpleDateFormat("dd/MM/YYYY");
Date date = df.parse(dateOfOrder);
Once you have the date, get day of week using Calendar.
Calendar c = Calendar.getInstance();
c.setTime(yourDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
int dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
Calculate number of days in the given week (and month).
int daysInMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
int currentMonth = c.get(Calendar.MONTH);
int prevWeekMonth = c.add(Calendar.DAY_OF_MONTH, -7).get(Calendar.MONTH);
c.setTime(yourDate);
int nextWeekMonth = c.add(Calendar.DAY_OF_MONTH, 7).get(Calendar.MONTH);
c.setTime(yourDate);
if (prevWeekMonth != currentMonth) {
// first or second week
if (dayOfMonth > dayOfWeek) {
// second week
numOfDaysInWeek = 7;
} else {
// first week
int firstDay = c.set(Calendar.DAY_OF_MONTH, 1).get(Calendar.DAY_OF_WEEK);
numOfDaysInWeek = 7 - firstDay;
}
} else if (nextWeekMonth != currentMonth) {
// last or second last week
if (dayOfMonth - dayOfWeek + 7 >= daysInMonth) {
// last week
numOfDaysInWeek = c.set(Calendar.DAY_OF_MONTH, daysInMonth).get(Calendar.DAY_OF_WEEK);
} else {
// second last week
numOfDaysInWeek = 7;
}
} else {
// middle weeks
numOfDaysInWeek = 7;
}
Note: the conditions are a bit rough and you might need to add 1 depending on whether dayOfWeek, dayOfMonth have 0 or 1 index.

Calendar display wrong starting day in android?

I have used below library for calendar but it display firstdayofweek is Monday i want to start day with sunday.
https://github.com/Applandeo/Material-Calendar-View
I have changed code accordingly but it still display date accordingly monday is firstday.
ArrayList<Date> days = new ArrayList<>();
// Get Calendar object instance
Calendar calendar = (Calendar) mCalendarProperties.getCurrentDate().clone();
// Add months to Calendar (a number of months depends on ViewPager position)
calendar.add(Calendar.MONTH, position);
// Set day of month as 1
calendar.set(Calendar.DAY_OF_MONTH, 1);
// Get a number of the first day of the week
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
// Count when month is beginning
int monthBeginningCell = dayOfWeek + (dayOfWeek == 1 ? 5 : -2);
// Subtract a number of beginning days, it will let to load a part of a previous month
calendar.add(Calendar.DAY_OF_MONTH, -monthBeginningCell);
/*
Get all days of one page (42 is a number of all possible cells in one page
(a part of previous month, current month and a part of next month))
*/
while (days.size() < 42) {
days.add(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
mPageMonth = calendar.get(Calendar.MONTH) - 1;
CalendarDayAdapter calendarDayAdapter = new CalendarDayAdapter(this, mContext,
mCalendarProperties, days, mPageMonth);
mCalendarGridView.setAdapter(calendarDayAdapter);
Try this:
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);

Calculation for the next birthday isn't accurate

I'm trying to calculate the remaining days to next birthday and setting an alarm to trigger 5 days before.
This is working fine, but it is not accurate.
For example, if I put 23. November 2013 I'm getting 366 days left and if I set some different month from current, I'm getting the right calculation, but not precisely.
For example, if I put 1. December 2013, I'm getting 8 days left and that is 30.
November 2015, not 1. December.
This is what i have done so far:
// Storing selected date
Date dt = null;
try { dt = dateFormatter.parse(dateSelected); } // dateSelected - Variable type String for storing the date user chose
catch (final java.text.ParseException e) { e.printStackTrace(); }
final Calendar BDay = Calendar.getInstance(); // Setting calendar for the next birthday
BDay.setTime(dt); // get selected date of birthday
final Calendar today = Calendar.getInstance(); // Setting calendar for the current date
// Take your DOB Month and compare it to current month
final int BMonth = BDay.get(Calendar.MONTH);
final int CMonth = today.get(Calendar.MONTH);
BDay.set(Calendar.YEAR, today.get(Calendar.YEAR));
// Result of next birthday
if(BMonth <= CMonth)
{
BDay.set(Calendar.YEAR, today.get(Calendar.YEAR) + 1);
}
// Result in millis
final long millis = BDay.getTimeInMillis() - today.getTimeInMillis();
// Convert to days
final long days = millis / 86400000; // Precalculated (24 * 60 * 60 * 1000)
// Test
final long test = today.getTimeInMillis() + 30*1000;
SimpleDateFormat dayFormatter = new SimpleDateFormat("EEEE");
//final String dayOfTheWeek = sdf.format(BDay.getTime());
final String dayOfTheWeek = dayFormatter.format(dt);
if (dateSelected != null) {
Intent intent = new Intent(AddBirthday.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(AddBirthday.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Set the alarm for a particular time.
// alarmManager.set(AlarmManager.RTC_WAKEUP, test, PendingIntent.getBroadcast(AddBirthday.this, 1 , intent, PendingIntent.FLAG_UPDATE_CURRENT));
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, test, AlarmManager.INTERVAL_DAY, pendingIntent);
}
SuperActivityToast.create(AddBirthday.this, "Days left for birthday: " + days + "\n" + "It will be: " + dayOfTheWeek,
SuperToast.Duration.LONG, Style.getStyle(Style.RED, SuperToast.Animations.FLYIN)).show();
you need to clear Hour, Minute and second in today variable
example:
if today is 23 Nov 2015 01:00:00 and BDay is 24 Nov 2015 00:00:00
millis = xxxx (23 hours)
then
days = millis / 86400000 // Precalculated (24 * 60 * 60 * 1000)
and the days will be 0

Scheduling a task for certain days of the week in Android

As the title implies, I'm looking to schedule a task to run on certain days at certain times. For example, I might have it run at 5:00 every Tuesday and Thursday. I've seen several scheduling methods for Android, but all of them seem to operate in the form of "do task after n delay" or "do task every n seconds".
Now I could probably jury-rig it by having it calculate the time to the next execution during the execution of the task itself, but that seems inelegant. Is there some better way to do this?
You've to set an Alarm to perform those tasks. Most probably you will end up calling a Service once the alarm is triggered:
private void setAlarmToCheckUpdates() {
Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.HOUR_OF_DAY)<22){
calendar.set(Calendar.HOUR_OF_DAY, 22);
} else {
calendar.add(Calendar.DAY_OF_YEAR, 1);//tomorrow
calendar.set(Calendar.HOUR_OF_DAY, 22); //22.00
}
Intent myIntent = new Intent(this.getApplicationContext(), ReceiverCheckUpdates.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)this.getApplicationContext().getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
However, if you need to set specifically a day:
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
if (weekday!=Calendar.THURSDAY){//if we're not in thursday
//we calculate how many days till thursday
//days = The limit of the week (its saturday) minus the actual day of the week, plus how many days till desired day (5: sunday, mon, tue, wed, thur). Modulus of it.
int days = (Calendar.SATURDAY - weekday + 5) % 7;
calendar.add(Calendar.DAY_OF_YEAR, days);
}
//now we just set hour to 22.00 and done.
Above code is a little bit tricky and mathematic. If you wan't something stupid aswell as easy:
//dayOfWeekToSet is a constant from the Calendar class
//c is the calendar instance
public static void SetToNextDayOfWeek(int dayOfWeekToSet, Calendar c){
int currentDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
//add 1 day to the current day until we get to the day we want
while(currentDayOfWeek != dayOfWeekToSet){
c.add(Calendar.DAY_OF_WEEK, 1);
currentDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
}
}

android alarmmanager repeat every month in specified date

I'm developing an application that can send a SMS in specified time, I have add some function on it, but i get stumped while i add function that can send a sms in every month on 14th, how can i make that function?
i have try the answer code on this link but didn't work.
I presume the problem is on the interval parameter in setRepeating function of AlarmManager class
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), interval , pendingIntent);
what the proper value of variable interval?
here interval is time in milliseconds between two alarms.
//e.g
long interval=5*60*1000;
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), interval , pendingIntent);
then my alarm will repeat every after 5 mins.
EDIT
int days=GetTotalDays(current_month);
interval=(days)*24*60*60*1000;
public int GetTotalDays(int current_month)
{
//here u can fetch current months total days
//suppose current month is 6(means july as it starts from 0)
//& u want to set alarm to next month(august)
//so get remaining days from calender of current month + day of next month
//e.g(14-7 to 14-8) so
//remaining days from calender of current month = 18(14-7 to 31-7)
//day of next month =14.
//so return would be (18+14-2=30).(-2.as it takes currentdate and nextdate also in calculation)
int currentdate=14;
int nextdate=14;
int totalDays=getDaysInMonthInPresentYear(6);
int myDays=(totalDays-currentdate)+nextdate;
return myDays-2;
}
public static int getDaysInMonthInPresentYear(int monthNumber)
{
int days=0;
if(monthNumber>=0 && monthNumber<12){
try
{
Calendar calendar = Calendar.getInstance();
int date = 1;
int year = calendar.get(Calendar.YEAR);
calendar.set(year, monthNumber, date);
days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
} catch (Exception e)
{
if(e!=null)
e.printStackTrace();
}
}
return days;
}
alarmManager .setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar1.getTimeInMillis() + AlarmManager.INTERVAL_DAY*30,
AlarmManager.INTERVAL_DAY*30, pendingIntent);
You can try like this

Categories

Resources