I have a AlarmManager in order to show notification. I don't want that I get a notification everytime I launch the app. I read a lot but nothing was satisfying. My method doNotification in MainActivity.java looks like this:
public void doNotification(){
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, i,PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP ,calendar.getTimeInMillis(), 1000*60*60*24*30 , pending); //every month
}
This method is in the OnCreate of my MainActivity class.
I know, that this is the reason why I get a notification everytime I launch my app.
My goal was to fire a notification every month, starting from the Date where the app was launched the first time. E.g User launches app on 5. July then you will get a notification on every 5th of every month.
How can I achieve this?
Thank you.
EDIT: According to the comments I used SharedPreferences is that a right use of it. Here is the new code:
public void doNotification(){
boolean isFirstAlarm = getSharedPreferences("ALARMFIRSTTIME",MODE_PRIVATE).getBoolean("isFirstAlarm",false);
if(!isFirstAlarm) {
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24 * 30, pending); //every month
getSharedPreferences("ALARMFIRSTTIME", MODE_PRIVATE)
.edit()
.putBoolean("isFirstAlarm",true)
.apply();
}
}
Related
I would like to set a notification at 8th of every month.
This is what i did:
Intent myIntent = new Intent(remember.this, receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(remember.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
// Set the alarm to start at approximately 8th of
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_MONTH, 8);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY*30, pendingIntent);
However what i got was a constant notification within minutes. And this does not go away.
Would appreciate your help here as i really do not know where went wrong.
Set calendar to upcoming 8th of the month.
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() , pendingIntent);
Inside receiver.class
public void onReceive(Context context, Intent intent) {
//do action needed
//invoke alarmManager in mainActivity
// cancel the previous alarm
// set the new alarm for the next month
}
How to create a AlarmManger which can be invoke on fixed date and time, This can be also repeat continuous by nature
unfortunately any of the options on the AlarmManager for repeating tasks doesn't allow such a fine control. Your best approach is to on every alarm, you re-schedule it for the next month.
PendingIntent pendingIntent = // set here your action
Calendar calendar = // set this guy to be the next 5th day
AlarmManager am = // get reference to the manager
am.set(RTC, calendar.getTimeInMillis(), pendingIntent);
on inside this Pending intent action you repeat the code. For example, let's say you want to launch a BroadcastReceiver
onReceive(Context context, Intent intent){
Calendar calendar = // set this guy to be the next 5th day
AlarmManager am = // get reference to the manager
am.set(RTC, calendar.getTimeInMillis(), pendingIntent);
}
to set the calendar object is easy:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY, 5);
I just read a good answer to do the same.
The code is-
Calendar cal=Calendar.getInstance();
cal.set(Calendar.MONTH,5);
cal.set(Calendar.YEAR,2012);
cal.set(Calendar.DAY_OF_MONTH,11);
cal.set(Calendar.HOUR_OF_DAY,16);
cal.set(Calendar.MINUTE,10);
cal.set(Calendar.SECOND,0);
Intent _myIntent = new Intent(getApplicationContext(), ReceiverClass.class);
PendingIntent _myPendingIntent = PendingIntent.
getBroadcast(getApplicationContext(), 123,
_myIntent, PendingIntent.FLAG_UPDATE_CURRENT| Intent.FILL_IN_DATA);
AlarmManager _myAlarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
//_myAlarmManager.set(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (10 * 1000), _myPendingIntent);
_myAlarmManager.set(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), _myPendingIntent);
This is explained in android-alarm-setting-with-specific-date.
in my task application, i want to create alarm service for multiple items. Here is the code i followed to create service. Lets assume, if there are more than 5 items present in list. then we will sent alarm service for 5 different times.
What if the user comes and edits the time?, how to update the system and make sure it triggers at new instance?. What if the user delete the task, how to quickly removes the registered alram for the deleted task?
What about uninstalling the app?, how to clear all the entries?, what if the system re-boots?
This is the code i'm following to register the task in alram services
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.set(Calendar.MONTH, 8);
Calendar_Object.set(Calendar.YEAR, 2012);
Calendar_Object.set(Calendar.DAY_OF_MONTH, 6);
Calendar_Object.set(Calendar.HOUR_OF_DAY, 14);
Calendar_Object.set(Calendar.MINUTE, 25);
Calendar_Object.set(Calendar.SECOND, 0);
Step 2:
We need to create an alarm which help us to invoke the BroadCastReceiver on our specified time.
// MyView is my current Activity, and AlarmReceiver is the BoradCastReceiver
Intent myIntent = new Intent(MyView.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MyView.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
/*
The following sets the Alarm in the specific time by getting the long value of the alarm date time which is in calendar object by calling the getTimeInMillis(). Since Alarm supports only long value , we're using this method.
*/
alarmManager.set(AlarmManager.RTC, Calendar_Object.getTimeInMillis(),
pendingIntent);
Use this method to set Alarm :
public static void startAlarm(Context context, int alarm_code, String time) {
String[] arrTime = time.split(":");
intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("CODE", alarm_code);
PendingIntent mAlarmSender = PendingIntent.getBroadcast(context,
alarm_code, intent, 0);
Calendar cal_alarm = Calendar.getInstance();
cal_alarm.setTimeZone(TimeZone.getDefault());
cal_alarm.set(Calendar.HOUR_OF_DAY, Integer.parseInt(arrTime[0]));
cal_alarm.set(Calendar.MINUTE, Integer.parseInt(arrTime[1]));
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal_alarm.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, mAlarmSender);
}
Here,"int alarm_code" is your unique code for particular item.
And for update alarm first cancel the existing alarm and set new alarm for new time.For that use this method :
public static void cancelAlarm(Context context, int alarm_code) {
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("CODE", alarm_code);
am.cancel(PendingIntent.getBroadcast(context, alarm_code, intent, 0));
}
Here,"int alarm_code" will be your unique code which you have used to set alarm.So that alarm with particular alarm_id will be cancel.You can also delete alarm with this method.
Same way you can clear all the alarms passing alarm_code to the given function.
You have to register receiver for system reboot and in onReceive of register you have to set all alarms again.
Hope this will help you.
My widget should refresh its textviews every day at 0:00. In the widget_provider.xml I set android:updatePeriodMillis="1000" but I read that the minimum update period is 30 minutes and I have to use alarmManager for this. So i want an alarm that triggers the refresh every day at 0:00. UpdateService.class handles the refreshing (setting texts for textviews based on date. The class is just not called until around half an hour after midnight)
In the public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) method I am using this code:
Intent intentN = new Intent(context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentN, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendarN = Calendar.getInstance();
calendarN.setTimeInMillis(System.currentTimeMillis());
calendarN.add(Calendar.HOUR_OF_DAY, 20);
calendarN.add(Calendar.MINUTE, 44);
calendarN.add(Calendar.SECOND, 5);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendarN.getTimeInMillis(), 7000, pendingIntent);
(I am trying with actual time now)
Is this the right place for this code? Why doesn't it work? I am using toast messages in UpdateService.java, but i never get the toast in the onStart(Intent intent, int startId) method apart from the first time, when the app in installed.
Thanks in advance
Update
With the help of probablykevin, i rewrite the code. I tried this code out in an Activity and it works:
Intent myIntent = new Intent(MainActivity.this, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 8000, pendingIntent);
Toast.makeText(MainActivity.this, "Start Alarm", Toast.LENGTH_LONG).show();
However if I modify it for the AppWidgetProvider class (and put it there ofc) it does not work. I never even get the toast msg:
Intent myIntent = new Intent(context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTimeInMillis(System.currentTimeMillis());
calendar2.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(), 8000, pendingIntent);
Toast.makeText(context, "Start Alarm", Toast.LENGTH_LONG).show();
First, your repeating time should be 24 * 60 * 60 * 1000, as it is in milliseconds.
Second your start time could be found using the time left until the next 0:00:
final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
long timeUntilMidnight = MILLIS_IN_DAY - (System.currentTimeMillis() % MILLIS_IN_DAY);
Then set your alarm by adding the time left to the current time:
alarmManager.setRepeating(...System.currentTimeMillis() + timeUntilMidnight, MILLIS_IN_DAY...);
Make sure you don't set multiple of the same alarm. I like to call
alarmManager.cancel(pendingIntent);
before setting it again just to be sure.
Ok, let me modify the question and make it much easier. I Hope you'll be able to get me the solution for this. Both the alarms should be scheduled simultaneously, which is not happening here. I am even using unique requestcode for the pending intent. HELP ME please.....
//On click Listener
private OnClickListener mOneShotListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, 0);
//I even tried sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, PendinIntent.FLAG_UPDATE_CURRENT);
//the alarm to go off 30 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
//adds 2 minutes to the time
calendar.add(Calendar.MINUTE, 2);
sender = PendingIntent.getBroadcast(AlarmController.this,1, intent,0);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender2);
}
};
OLD Question:
I want to set two alarms at the same time for two different operations to be performed.
For Eg. A user sets alarm at 2'O clock and sets the duration to 15 mins. The first alarm should fire at 2'O clock which performs function1 and the second alarm should fire at 2:15 as the user specified the duration as 15 mins which performs the function2. This operation should be repeated everyday at 2'O clock unless the user changes the time.
I am calling this both functions on button click:
On Click Event
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
..........
..........
new ReminderManager(this).setReminder(mRowId, mCalendar);
new ReminderManager(this).wakeReminder(mRowId, mCalendar, duration);
}
}
The setReminder contains
//sets alarm at 2'O clock
public void setReminder(Long taskId, Calendar when, String duration){
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext,(int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}
The wakeReminder contains
//adds duration i.e. 15mins
public void wakeReminder(Long taskId, Calendar when, String duration){
Intent i = new Intent(mContext, OnAlarmReceiverWake.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
Long d = Long.parseLong(duration);
Long mins = d*60*100;
Long milli = when.getTimeInMillis() + mins;
PendingIntent pi = PendingIntent.getBroadcast(mContext, (int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, milli, pi);
}
I have noticed that whenever mAlarmManager.set(); is executed successfully the LogCat shows notification like
"enqueueToast pkg=com.jellboi.android.togglemode callback=android.app ITransientNotification$stub$proxy#43c0c5f8 duration=0"
but when I set both the alarms simultaneously the notification is not shown when the mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); is executed
but the notification is shown when mAlarmManager.set(AlarmManager.RTC_WAKEUP, milli, pi); is executed. Also the notification is set for the original time i.e. 2'O clock and not after adding 15mins to it's duration.
Please help, I tried a lot of ways to call this functions at different places like after the 1st alarm is fired but all in vain.
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, 0);
You have problem in this line. If you want to simultaneously fire two alarma then you should do something like this
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,giveUniqueRequestIdsHere, intent, 0);
sender = PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), i, PendingIntent.FLAG_ONE_SHOT);
Do the same for your PendingIntent.getActivity();
Hi try using this to generate request I was generating my own request code but this line worked for me
final int intent_id = (int) System.currentTimeMillis();
When launch new OneShotAlarm.class, it have to design launch mode. Default setting would ignore the second time launch, if the first instance still existed.
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
seems like you forgot to set "sender2" before your second call.
you change the value of sender, then put sender2 as the argument.
You can create an array of your task in the Service class and set the array in the for loop, inside the for loop you can call your task simultaneously at the same time.
Try this:
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
cal.clear();
Cursor c = database.query(mArray.get(mPosition), new String[]{"days"},"days"+"!="+0, null, null, null, null);
cal.set(Calendar.YEAR,2011);
cal.set(Calendar.MONTH,date.getMonth());
cal.set(Calendar.DAY_OF_MONTH,date.getDate());
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(nextScreen.this, AlaramReciver.class);
i.putExtra("Start",mArray.get(mPosition));
Editor medit = getSharedPreferences("Start", 0).edit();
medit.putString("Start", mArray.get(mPosition));medit.commit();
PendingIntent pendingintent = PendingIntent.getBroadcast(this,mPosition, i, 0);
mgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingintent);
You have set to the time like this, and once you set time in alarm manager it will automatically call the functions daily. Use different request code for pendingintent.
If you want call second function. You just add the time in 15 min in the
cal.set(Calender.MINUTE,min+15);