Understanding My AlarmManager Logic - android

I need help in understanding the logic that I have implemented in my app using AlarmManager, since the logic is not working as I expected. I am new to Android development and a self-learner.
The Logic :
User selects a time in Main Activity using a button.
That time value is used for setting repeating alarm in Another activity.
When the alarm goes of A dialog box appears.
Main Activity:
static long ATfrom_to_millisec;
case R.id.ATfrom:
final Calendar ATfromC = Calendar.getInstance();
ATfromHour = ATfromC.get(Calendar.HOUR_OF_DAY);
ATfromMinute = ATfromC.get(Calendar.MINUTE);
// Launch Time Picker Dialog
TimePickerDialog ATfromtpd = new TimePickerDialog(MainActivity.this,
new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
//Converting to milli seconds to use in AlarmManager
ATfrom_to_millisec = ((hourOfDay * 60 * 60 * 1000) + (minute * 60 * 1000));
String AM_PM;
if (hourOfDay < 12) {
AM_PM = "AM";
} else {
AM_PM = "PM";
if (hourOfDay > 12) {
hourOfDay = hourOfDay - 12;
}
}
if (minute < 10) {
ATfrom.setText(hourOfDay + ":0" + minute + " " + AM_PM);
} else {
ATfrom.setText(hourOfDay + ":" + minute + " " + AM_PM);
}
In the above logic the time selected by the user is converted to milliseconds and stored in a public static variable so that it can be used by other activities.
Alarm Activity :
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()){
case R.id.bReminder:
try {
//Receiving the static variable's value from MainActivity
long AT_from = MainActivity.ATfrom_to_millisec;
float cov = (float)(AT_from/1000/60/60);
//Toast to check if the time value is passed correctly
toast.makeText(getApplicationContext(), String.valueOf(cov), toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, Notifier.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this.getApplicationContext(),
12345, intent, 0);
//Logic for Repeating Alarm that uses the time value from MainActivty as starting time and repeating it every 10 seconds.
// i.e. the alarm should go off after 10 seconds from the use selected time and repeat after 10 seconds.
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, AT_from + (10*1000), 10*1000, pendingIntent);
} catch (Exception e) {}
break;
case R.id.bReminderStop:
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.cancel(pendingIntent);
break;
}
}
When alarm is set with the above implemented logic , The alarm goes of immediately once it is set and repeats with an interval of 1 minute.
But I implemented my logic expecting the alarm to go of 10 seconds from the time set by user and repeat after every 10 seconds
I am not able to understand the mistake implemented in my logic.
Also in the toast I am not getting the decimal value of float cov
(eg : 11:30 PM must be displayed as 23.5 .But it is displayed as 23.0)
Dialog Activity when Alarm goes off :
public class Notifier extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("HydrateTime");
alertDialogBuilder.setMessage("Enter the amount of water");
alertDialogBuilder.setPositiveButton("Update", null);
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
I want the above Activity to be invoked when the Alarm goes off. Is the above implemented logic enough to make a Dialog window appear when an activity goes of?
Note : I am using a general activity definition in the Android Manifest.
like :
<activity
android:name=".Notifier"
android:label="#string/app_name">
</activity
Kindly request answers for the below questions :
Am I passing the time value set in the MainActivity to the AlarmManager in another activity correctly?
What is the mistake in my Alarm logic and how to rectify it such that the alarm goes of as per my requirement?
Is the definition for the dialog box correct? should there any more definitions in Manifest? should I create any layout file for the dialog activity? Should I extend my Notifier class with Dialog class instead of Activity class?

The logic has a minor flaw. You see, with alarms if the time to fire has already passed, then the alarm will fire immediately. For eg: if I set an alarm with milli seconds for 2 Jan 1983, it would fire immediately. If you notice, you are doing something similar.
To fix it, simply add this in your Alarm Activity:
// Will trigger after 10 secs from set time
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + AT_from + (10*1000), 10*1000, pendingIntent);
I am not sure what is causing the interval problem though. It seems fine to me.

Related

I have used alarm manager to schedule a notification, but is not working if i used the calender time

This is the code which i have used on click of my set alarm button
alarmOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,timePicker.getHour());
calendar.set(Calendar.MINUTE,timePicker.getMinute());
int hourString = timePicker.getHour();
int minuteString = timePicker.getMinute();
//intent.putExtra("extra","alarm_on");
setAlarmTxt("Alarm set to "+ hourString+":"+minuteString);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
//alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),0,pendingIntent);
// sendBroadcast(intent);
}
});
When i used this code, it is working...
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,SystemClock.elapsedRealti
me(),pendingIntent);
Use RTC_WAKEUP to use system current time and ELAPSED_REALTIME_WAKEUP to specify time in interval of time elapsed since device boot time.
That is, either
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,SystemClock.elapsedRealti
me(),pendingIntent);
or
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
See this for details

Setting up alarm for android application using AlarmReceiver and OnBootReceiver

I've browsed through numerous StackOverflow and Youtube tutorials to create an alarm service (to be used as a part of a larger app that I am building), yet it seems that all of them give different, non-working answers or rely on deprecated methods that do not work anymore.
My current issue with the following code is that when I reach the following code: alrmMgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendInt); it does not seem to send the appropriate time to the alarm manager (it more or less always sends the current time).
However, I know for a fact that calendar.getTimeInMillis() gives me the time that I have set (the setAlarmText textView changes properly). I was wondering if anyone has any experience with this?
Furthermore, the AlarmReceiver class never seems to be called even though I was under the impression that the AlarmManager takes care of that for you.
Code is attached below:
public class AlarmStartPage extends Activity {
AlarmManager alrmMgr;
PendingIntent pendInt;
private TimePicker alrmTimePicker;
private static AlarmStartPage inst;
Intent myIntent;
private TextView alrmStatusView;`
protected static AlarmStartPage instance() {
return inst; // returns an instance of the current Activity
}
#Override
public void onStart() {
super.onStart(); // calls the super classes onStart, and then sets the instance to the current one
inst = this;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_start_page); // sets the various buttons and other containers on the website
alrmTimePicker = (TimePicker) findViewById(R.id.alarmTimePicker);
ToggleButton alrmTogg = (ToggleButton) findViewById(R.id.toggleAlarmButton);
alrmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
alrmStatusView = (TextView) findViewById(R.id.alarmStatus);
setVolumeControlStream(AudioManager.STREAM_ALARM); // sets the volume to be controlled to the audiomanager so that the user can control the alarm's volume
}
public void onToggleClicked(View view) {
if (((ToggleButton) view).isChecked()) {
Log.d("MyActivity", "Alarm On!");
int hourToSet, minuteToSet; // if the toggle button is pushed, then it creates an alarm. Otherwise it cancels a previously created alarm
Calendar calendar = Calendar.getInstance();
if (Build.VERSION.SDK_INT >= 23) // the code here and the one below in the else statement are identical except for which API they cater to
{
hourToSet = alrmTimePicker.getHour();
minuteToSet = alrmTimePicker.getMinute(); // gets the TimePicker's time that the user wants if using Android Marshmallow
} else {
hourToSet = alrmTimePicker.getCurrentHour(); // gets the TimePicker's time that the user wants if using any Android Lolipop or below
minuteToSet = alrmTimePicker.getCurrentMinute();
}
// this is the code to actually do the "magic" of the REM time
int currhr = calendar.get(Calendar.HOUR_OF_DAY); // gets the current time from the system's clock
int currmin = calendar.get(Calendar.MINUTE);
boolean lessThan90 = false; // boolean to check if the current alarm is less than 90 Minutes away (1 REM cycle)
int hrDiff = 0;
int minDiff = 0;
if (hourToSet >= currhr) {
hrDiff = hourToSet - currhr; // calculating the difference between the current hour and the hour of the alarm to get the difference in the time
if (hrDiff == 0) {
if (minuteToSet > currmin) // if the alarm is for after the current time, but same hour, then it is less than 1 hour away
minDiff = minuteToSet - currmin;
else {
hrDiff = 23; // otherwise the alarm us for more than 23 hours away (same hour, but earlier time)
minDiff = 60 - (currmin - minuteToSet);
}
} else {
if (minuteToSet > currmin)
minDiff = minuteToSet - currmin;
else {
hrDiff--;
minDiff = 60 - (currmin - minuteToSet);
}
}
if (60 * hrDiff + minDiff < 90) // if prior to the 15 min shift, the alarm time is less than 90 minutes away, then it will be set as the alarm time
lessThan90 = true;
}
currmin += 15; // add 15 min to the current time, and below, change the hour and minute accordingly
if (currmin >= 60) {
currmin = currmin % 60;
currhr++;
if (currhr >= 24)
currhr = currhr % 24;
}
if (!lessThan90) // only if the alarm time is more than 90 minutes away, it will try to do this (which it will try to do
{ // by defualt since lessThan90 is initalized to false (or it is set to true by the above if else statement
if (hourToSet >= currhr) {
hrDiff = hourToSet - currhr;
if (hrDiff == 0) // same logic as earlier, checks if the same hour as the alarm, then checks if the alarm is before or after the current time
{
if (minuteToSet > currmin) // if the alarm is set for a later time (which means that it is less than 90 minutes away)
minDiff = minuteToSet - currmin;
else // otherwise the alarm is set for 23 hours and some minutes away
{
minDiff = 60 - (currmin - minuteToSet);
hrDiff = 23;
}
} else {
if (minuteToSet > currmin)
minDiff = minuteToSet - currmin;
else {
hrDiff--;
minDiff = 60 - (currmin - minuteToSet);
}
}
} else if (hourToSet < currhr) // if the alarm time is before the current time (then it must loop over midnight and restart from 0 again)
hrDiff = 24 - (currhr - hourToSet);
}
int totalMinutesInBetween = 60 * hrDiff + minDiff;
if (totalMinutesInBetween < 90) // if the total minutes between the alarm and the current time (after the 15 min shift) is less than 90 minutes
lessThan90 = true; // it is less than 1 REM shift away
if (!lessThan90) // If there are more than 90 minutes of difference, then a REM cycle is ACTUALLY possible
{
int possibleRem = totalMinutesInBetween / 90; // the possible amount of REM cycles between now and the alarm time
for (int i = 0; i < possibleRem; i++) {
currhr++; // the time is altered by 90 minute cycles (looping around after 60 minutes or after 24 hours) to get the appropiate REM time
if (currhr >= 24)
currhr = currhr % 24;
currmin += 30;
if (currmin >= 60) {
currmin = currmin % 60; // looping the minutes over 60
currhr++;
if (currhr >= 24)
currhr = currhr % 24; // looping the hours after 24 hours
}
}
hourToSet = currhr;
minuteToSet = currmin;
}
calendar.set(Calendar.HOUR_OF_DAY, hourToSet); // the calendar sets the final REM time
calendar.set(Calendar.MINUTE, minuteToSet);
myIntent = new Intent(AlarmStartPage.this, AlarmReceiver.class);
pendInt = PendingIntent.getBroadcast(AlarmStartPage.this, 0, myIntent, 0); // new intent as well as a pending intent to notify the system of the alarm (uses Alarm Receiver and Alarm Service)
alrmMgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendInt); // alarmmanager is used to set the alarm
if (minuteToSet > 9)
setAlarmText("An alarm has been placed for " + hourToSet + ":" + minuteToSet + " (in military time). If you shut down" +
" this app, please do not open it again until the alarm that you set is over (otherwise the alarm will reset itself)."); // alarm text is changed to notify the user
else
setAlarmText("An alarm has been placed for " + hourToSet + ":0" + minuteToSet + " (in military time). If you shut down" +
" this app, please do not open it again until the alarm that you set is over (otherwise the alarm will reset itself).");
} else {
alrmMgr.cancel(pendInt); //cancels the current Intent (effectively stopping the alarm)
stopService(myIntent);
setAlarmText("The previous alarm was canceled."); // changes the text on the textbox under the time picker
Log.d("MyActivity", "Alarm OFF");
}
}
public void setAlarmText(String textToShow) {
alrmStatusView.setText(textToShow); // sets the text for the textbox below the TimePicker
}
#Override
public void onDestroy() {
super.onDestroy(); // calls the super classes destroy method to destroy the activity
}
}
AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {`
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); //this will sound the alarm tone
Log.d("Creating Alarm", "Used ALARM for ringtone " + alarmUri);
System.out.println("logging that it got to this part");
if (alarmUri == null) {
Log.d("Creating Alarm", "Used the notification instead of alarm for ringtone");
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
ringtone.play(); // plays the ringtone of the phone as the alarm
Intent service_intent = new Intent(context, AlarmService.class);
context.startService(service_intent);
//ComponentName comp = new ComponentName(context.getPackageName(), AlarmService.class.getName());
//startWakefulService(context, (intent.setComponent(comp))); // sends the notification message and wakes up the phone
setResultCode(Activity.RESULT_OK);
}
}
AlarmService.java:
public class AlarmService extends IntentService {
private NotificationManager alarmNotificationManager;`
public AlarmService() {
super("AlarmService");
}
#Override
public void onHandleIntent(Intent intent) {
sendNotification("Wake Up! Your alarm has been rung!!!!"); // sends the notification to the phone that the alarm is ringing
}
private void sendNotification(String msg) {
Log.d("AlarmService", "Preparing to send notification...: " + msg);
alarmNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, AlarmStartPage.class), 0); // creates the notification and sets the icon for the notification
NotificationCompat.Builder alarmNotificationBuilder = new NotificationCompat.Builder(
this).setContentTitle("Alarm").setSmallIcon(R.mipmap.ic_launcher).setStyle(new NotificationCompat.BigTextStyle().bigText(msg)).setContentText(msg);
alarmNotificationBuilder.setContentIntent(contentIntent);
alarmNotificationManager.notify(1, alarmNotificationBuilder.build());
Log.d("AlarmService", "Notification sent.");
}
}
OnBootReceiver:
public class OnBootReceiver extends BroadcastReceiver {
private static final int WAITING_PERIOD = 10000; // 10 seconds (aka 10000 milliseconds)`
#Override
public void onReceive(Context context, Intent intent)
{
AlarmManager aMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); // allows previously created alarms to still exist on bootup.
Intent i = new Intent(context, AlarmReceiver.class);
PendingIntent pI = PendingIntent.getBroadcast(context, 0, i, 0);
aMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), WAITING_PERIOD, pI);
}
}
Code can also be found on https://github.com/sahilmgandhi/REM.my/tree/master/app/src/main/java/com/sahilmgandhi/remmy
Any help would be appreciated.
Edit:
This is the solution we came up with in case if it helps anyone:
Nick: So the broadcast does start the service which runs the notification, but the issue is where the sound is supposed to be changed and it doesn't?
Nick: Ok so is there any reason you are having the sound play from the Receiver and not have the sound play straight from the notification object? I think that would work
Me: Hmm, i was following several different tutorials and all of them seemed to have it in the receiver.
Nick: in the service sendNotification method try to change to this:
private void sendNotification(String msg) {
Log.d("AlarmService", "Preparing to send notification...: " + msg);
alarmNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, AlarmStartPage.class), 0); // creates the notification and sets the icon for the notification
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
NotificationCompat.Builder alarmNotificationBuilder = new NotificationCompat.Builder(
this)
.setContentTitle("Alarm")
.setSmallIcon(R.mipmap.ic_launcher)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setSound(soundUri);
alarmNotificationBuilder.setContentIntent(contentIntent);
alarmNotificationManager.notify(1, alarmNotificationBuilder.build());
Log.d("AlarmService", "Notification sent.");
}
Nick: Pretty sure that's the correct way to do notification sounds now.. old way with Ringtone is probably deprecated. Comment the ringtone part out for now
Nick: And the correct way to run a service from AlarmManager is to have it fire a BroadcastReceiver which then starts your IntentService.
Nick: I forget exactly why that's the case.. but you definitely want to do it that way. I've thought about running everything in the receiver but its best to do it that way, alarm -> receiver -> IntentService with all the code in it
To get your alarm to fire at the correct time, add this line after you instantiate your Calendar object in your AlarmStartPage activity:
calendar.setTimeInMillis(System.currentTimeMillis());
So your code should now look like this when you create your Calendar:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
This will make sure the other Calendar parameters are set correctly, because before you had it just setting the hour/minute but the rest was not fully configured.

Calendar, execute code every 24 hours

I would like to execute a piece of code every 24 Hours however I'm not sure how to do this.
I have some code that sets the time that I would like the cycle to start but not sure how to execute the end time
int startDay = 00; // 12am
int end = 24; // 12 pm
int hours = (end - startDay) % 24; //difference will be 24 hours
Calendar calInstanceOne = Calendar.getInstance();
// set calendar to 12 am
calInstanceOne.set(Calendar.HOUR_OF_DAY, startDay);
calInstanceOne.set(Calendar.MINUTE, 0);
calInstanceOne.set(Calendar.SECOND, 0);
calInstanceOne.set(Calendar.MILLISECOND, 0);
Do I create another Calendar instance, set to 12pm? and compare the two? Would really appreciate any insight into this.
I would like to execute a piece of code every 24 Hours
Use AlarmManager, in conjunction with either WakefulBroadcastReceiver or my WakefulIntentService. Ideally, use setInexactRepeating() on AlarmManager for INTERVAL_DAY, to allow Android to slide the actual time around to best save battery for the user.
You can use AlarmManager to make actions periodically:
Intent intent = new Intent(this, MyStartServiceReceiver.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, <24h in msecs>, pendingIntent);
Then you should register your BroadcastReceiver in the manifest and call the method you want to execute from this receiver.
First store your current time then whenever app will be open compare current time with previous store time if its greater or equal 24 hour
execute your code.
You may have several choices, let me outline the easiest one. The strategy is to simply use the system time to execute twenty four hours later:
package com.test;
import java.util.Calendar;
public class ExecuteCheck {
//Class fields
/* Number of milliseconds in a day
*
*/
private static final long C_DAY=24*60*60*1000;
//Object fields
/* Time last executed (or beginning of cycle), in milliseconds;
*
*/
private long lastExecuted = System.currentTimeMillis();
public ExecuteCheck() {
}
/** Set the current execution cycle time to now
*
*/
public void setExecutionTimeToNow() {
lastExecuted = System.currentTimeMillis();
}
/** Set the execution cycle time to be the value in the calendar argument.
* #param cal
*/
public void setExecutionTime(Calendar cal) {
lastExecuted = cal.getTimeInMillis();
}
/** Is it more than twenty-four hours since the last execution time?
* #return
*/
public boolean isTimeToExecute() {
return (System.currentTimeMillis() - lastExecuted) > C_DAY;
}
}

Android Give Notification on a specific day

I'm trying to build an app where I'm building a countdown timer to a specific date and time. Now I've built the countdown timer using the android countdown timer class and it's working properly.
Now what I want to do is show a notification method in the onFinish() of the Countdown Timer saying that the event has arrived. I want the notification to show even if the app isn't running. Here is my code so far:
new CountDownTimer(timer.getIntervalMillis(), 1000) {
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
int days = (int) ((millisUntilFinished / 1000) / 86400);
int hours = (int) (((millisUntilFinished / 1000) - (days * 86400)) / 3600);
int minutes = (int) (((millisUntilFinished / 1000)
- (days * 86400) - (hours * 3600)) / 60);
int seconds = (int) ((millisUntilFinished / 1000) % 60);
String countdown = String.format("%02d:%02d:%02d:%02d", days,
hours, minutes, seconds);
countdownTimer.setText(countdown);
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
countdownBegins.setVisibility(View.GONE);
countdownTimer.setText("SYMAGINE IS HERE!!");
}
}.start();
How do I show a notification when the countdown timer has finished. Even at the chance that the app may not be running. I've seen AlarmManager but somehow i didn't understand it. Help is appreciated with proper explanation since i'm kind of a newbie.
You should use android AlarmManager. When you Schedulle an alarm with it, it will trigger the event( it doesnt matter if your app is running or not, it will trigger the event ).
Since you want to show a notification i would suggest that you start a Service when the alarm triggers, and build your notification from the service.
Take a look at this: http://www.techrepublic.com/blog/software-engineer/use-androids-alarmmanager-to-schedule-an-event/
Here is an example : How to start Service using Alarm Manager in Android? --> it uses a repeating alarm but the logic is the same.
Try out a few examples and you will get the hold on of it, AlarmManager is actually very simple to use as you will see from the above examples.
Bellow example taken from : How to schedule a task using Alarm Manager
public void scheduleAlarm(View V)
{
// time at which alarm will be scheduled here alarm is scheduled at 1 day from current time,
// we fetch the current time in milliseconds and added 1 day time
// i.e. 24*60*60*1000= 86,400,000 milliseconds in a day
Long time = new GregorianCalendar().getTimeInMillis()+24*60*60*1000;
// create an Intent and set the class which will execute when Alarm triggers, here we have
// given AlarmReciever in the Intent, the onRecieve() method of this class will execute when
Intent intentAlarm = new Intent(this, AlarmReciever.class);
//Get the Alarm Service
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP,time, PendingIntent.getBroadcast(this,1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(this, "Alarm Scheduled for Tommrrow", Toast.LENGTH_LONG).show();
}
AlarmReciever Class
public class AlarmReciever extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
// Your Code When Alarm will trigger
}
}

WakefulIntentService starts immediately after scheduling

I am attempting to use CommonsWare's WakefulIntentService in a new application, specifically its ability to easily schedule the intent service to run at a later time.
I have a PreferenceActivity that allows the user to pick the schedule that the service is run (daily at 5am for example). Once the user makes a change to the preference value, I call:
AutoDownloadIntentServiceAlarmListener alarmListener = new AutoDownloadIntentServiceAlarmListener();
alarmListener.setForcedHour(5); // we want to schedule alarm for 5am everyday.
WakefulIntentService.scheduleAlarms(alarmListener, this, true);
For some reason, the desired IntentService (that extends WakefulIntentService) immediately starts up and performs its work.
Here is the implementation of of AutoDownloadIntentServiceAlarmListener:
public class AutoDownloadIntentServiceAlarmListener implements WakefulIntentService.AlarmListener {
private static final String TAG = "AutoDownloadIntentServiceAlarmListener";
private int mForcedHour = -1;
#Override
public long getMaxAge() {
return AlarmManager.INTERVAL_DAY * 2;
}
public void setForcedHour(int forcedHour) {
mForcedHour = forcedHour;
}
#Override
public void scheduleAlarms(AlarmManager alarmManager, PendingIntent pendingIntent, Context context) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
String autoDownloadTimePref = MyApplication.getInstance().getPrefs().getString("autoDownloadEpisodesSchedule", "0");
int hourOfAlarm = Integer.parseInt(autoDownloadTimePref);
// if this class has been created with a specific hour
// use it instead of the value obtained from SharedPreferences above.
if (mForcedHour > -1) {
Log.w(TAG, "Forced hour has been set for this AlarmListener. " + mForcedHour);
hourOfAlarm = mForcedHour;
}
calendar.set(Calendar.HOUR_OF_DAY, hourOfAlarm);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Log.d(TAG, String.format("Scheduled inexact alarm for %d", hourOfAlarm));
}
#Override
public void sendWakefulWork(Context context) {
Intent serviceIntent = new Intent(context, AutoDownloadIntentService.class);
WakefulIntentService.sendWakefulWork(context, serviceIntent);
}
}
It is my intention that the service does not startup as soon as it is scheduled, and instead starts up only at 5am the next day. (and continues to repeat on this schedule indefinitely, or until the user elects to disable or change its schedule)
What am I doing wrong?
It is my intention that the service does not startup as soon as it is scheduled, and instead starts up only at 5am the next day.
Except that's not what your code does, ~80% of the time. Your code says that it should run at 5am today, as you are getting the current time and not changing the day. Most of the time, 5am today is in the past, and so AlarmManager will immediately do its work.
You need to see if your calculated Calendar is older than now, and if so, add a day.

Categories

Resources