My application have a Service that every X minutes do same action on the database than it stopSelf() and into onDestroy method I have palced this code for restart the service after same time:
#Override
public void onDestroy() {
super.onDestroy();
Intent intent_service = new Intent(context,vampireService.class);
PendingIntent pintent = PendingIntent.getService(context, 0, intent_service,0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.ELAPSED_REALTIME,SystemClock.elapsedRealtime()+ 4500000, pintent);
}
But I don't understand why if my phone go in sleep mode the service not restart ! Appears that the count time of AlarmManager to start when I power back up the display....it's possibile ? If yes, how can I resolve this problem ?
Thanks
From the documentation for ELAPSED_REALTIME...
This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.
Try using ELAPSED_REALTIME_WAKEUP to see if that helps (not sure if it will work for a service however).
You can (and should) schedule your Service to run every X time, using the Alarm Manager. You have this option of setRepeating.
Related
I have an application that does something in a service triggered by an alarm every 10 minutes while the app is in the background. I want the Alarm to keep going off even if the OS kills the app (So its dead and have to relaunch) and only kill it if the user actually removes the app from recent apps or force kills it from settings (or is logged off but that already works). I have tried many different approaches, latest I tried this http://www.dotkam.com/2011/01/10/android-prefer-alarms-and-intent-receivers-to-services/ without any luck. My Alarm looks like this.
if(ActivityLifecycleHandler.isApplicationInForeground()) {
return; // If App is in foreground do not start alarm!
}
String alarm = Context.ALARM_SERVICE;
AlarmManager am = ( AlarmManager ) context.getSystemService( alarm );
Intent intent = new Intent(locationBroadcastAction);
PendingIntent pi = PendingIntent.getBroadcast( context.getApplicationContext(), 0, intent, 0 );
int type = AlarmManager.ELAPSED_REALTIME_WAKEUP;
// Set trigger time to 0, because want to fire off the first one instantly
am.setRepeating( type, 0, ONE_MINUTE, pi );
And the BroadcastReceiver:
public class LocationBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent ) {
Intent myIntent = new Intent( context, LocationService.class );
context.startService( myIntent );
}
}
Any idea of what I am doing wrong? Everything works fine until the OS kills the app.
The alarm should goes off if the app was killed, even if if was removed from the recent app (but not if it was force-stopped).
It is actually the whole point of using the AlarmManager :
Note: The Alarm Manager is intended for cases where you want to have
your application code run at a specific time, even if your application
is not currently running. For normal timing operations (ticks,
timeouts, etc) it is easier and much more efficient to use Handler.
You can see if the alarm is still there with :
adb shell dumpsys alarm
What is probably happening is that the device is woken up to receive the alarm, but fall asleep again as soon as the receiver finishes, before the service can start.
The receiver should take a wake lock (to be released by the service). The support library provides a WakefulBroadcastReceiver which does exactly that :
Helper for the common pattern of implementing a BroadcastReceiver that
receives a device wakeup event and then passes the work off to a
Service, while ensuring that the device does not go back to sleep
during the transition.
I have a very simple alarm manager to do things while the device is awake. So I figured AlarmManager.RTC was my best approach. As according to AlarmManager API the device is supposed to ignore the next occurring alarm until the device wakes up, then will it send its pending intent instructions.
Here is the code that I have scheduling the Alarm:
Intent intent = new Intent(getApplicationContext(), WorkerService.class);
PendingIntent pIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 10000, pIntent);
And here is the code inside the "WorkerService.class"
public void onCreate() {
super.onCreate();
stopSelf();
}
public void onDestroy() {
super.onDestroy();
Log.i("Service Status", "Service exited");
}
What am i doing wrong here?
Now I know I can write a screen receiver, but then I would have to have another service open to hold that receiver (kinda annoying) when alarm manager is supposed to be ignoring my alarm when the screen is off.
I used Log.i to inform me if the service ran. I was able to tell in eclipse's logcat what the output was by using ADB Over WiFi this way the device was allowed to sleep.
Thanks guys, im truly stumped.
I want to schedule a service to run every minute and check if my app is still running. (I want to reopen the application if it is closed).
Also, I still want this service to run every minute if my application was force killed by task manager.
Thanks!
Also, I still want this service to run every minute if my application was force killed by task manager
This is not possible as of Android 3.1. If the user goes into Settings and force=stops your app, nothing of your app will run again, until the user manually launches one of your components.
If your process is terminated for other reasons (e.g., ordinary task-killer app from the Play Store, swiping your task away from the Recent Tasks list), your alarms scheduled with AlarmManager should remain intact, per Lucifer's suggestion.
im writing a "Parent Control" app which is installed on the child's phone.
Any child sufficiently intelligent to use a phone will be sufficiently intelligent to reboot their device in safe mode and get rid of your app.
Use AlarmManager class, it works even if your device is in sleep mode.
private static Intent alarmIntent = null;
private static PendingIntent pendingIntent = null;
private static AlarmManager alarmManager = null;
// First Creating an Intent
alarmIntent = new Intent ( context, yourClass.class );
// Create an Pending Intent which will Broadcast the Intent
pendingIntent = PendingIntent.getBroadcast(context, 234324243, alarmIntent, 0 );
// Set the AlarmManager class
alarmManager = ( AlarmManager ) context.getSystemService( ConstantCodes.ALARM_SERVICE );
// Set Repeating time interval
alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, Interval * 1000, Interval * 1000, pendingIntent );
AlarmManager consumes lesser battery power than TimerTask or Thread. It works like painless AsyncTask.
I have an App with a workflow that calls many activities, some of them it finishes and others leaves them active as the user progresses through it. BUT I cannot switch off my alarm service which continues even when the home button is actuated and the app killed.
Oh sure - the force close in settings will stop the alarm service very well (its the only way to kill it). I cannot stop alarm from my app program since nothing tells me when the app has been closed.
None of the life cycle methods onDestroy() or on Stop() work because the home button can be actuated during any of 15 activities and onDestroy() is not called for a long time after on any activity.
BUT I cannot switch off my alarm service which continues even when the home button is actuated and the app killed.
Then do not register the alarm. AlarmManager is designed to execute your code periodically when your code is not already running. For something that is purely within an activity, use postDelayed().
When you press the home button, your app isn't--and isn't supposed to--shut down. It is "frozen" by a call to onSaveInstanceState(Bundle). If you click on your app icon, it will be restarted and resumed just as if there had been a giant pause in the system clock (or, if it was killed off by the system, re-created from the bundle you set in onSaveInstanceState). Typically you would turn suspend or cancel time-related activity in onPause, because, in a sense, time stops for your app at that point.
What are you using alarms for that they need to be stopped when the app exits? The whole point of them, I thought, was to invoke something in your app up at a particular time even if it wasn't running.
Just do like this....
AlarmManager alarm;
PendingIntent pintent;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(this, TestService.class);
pintent = PendingIntent.getService(this, 0, intent, 0);
alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int i;
i=30;
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), i* 1000, pintent);
System.out.println("service going to start-----------");
startService(new Intent(getBaseContext(), TestService.class)); // Here start your service
If you want to stop your service means you should stop your alarm service once. In onBackPressed() method's ok button would be finish your activity. Within that button you should add the following code.
alarm.cancel(pintent);
This will stop your service add alarm when you exit from your application. All the best.
I need to have a process run whenever the end-user clicks on a Submit button. The application needs to try to process the data on the screen every X minutes, Y times, even if the the application is down. So, it will need to attempt to do some processing until one of the following occurs:
1) The processing is successful for the data that was submitted
2) The processing has been retried Y times and still never succeeded
3) The application is terminated by the OS or the phone is turned off.
If the end-user's phone is still on but the application has stopped,
what's the correct interface to use to accomplish this?
If I use Handler/Runnable, that only works as long as the application stays active.
AlarmManager looks like it's used when you want processing to run at a specific time.
Any suggestions will be greatly appreciated!
I use this method to set an alarm.
private void setAlarm(){
Context context = getApplicationContext();
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnAlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
myCal = Calendar.getInstance();
myCal.setTimeInMillis(myPrefs.getLong("time", 0));
mgr.set(AlarmManager.RTC_WAKEUP, myCal.getTimeInMillis(), pi);
Log.i(myTag, "alarm set for " + myCal.getTime().toLocaleString());
Toast.makeText(getApplicationContext(),"Alarm set for " + myCal.getTime().toLocaleString(), Toast.LENGTH_LONG).show();
}
inside my onAlarmReciever onRecieve method is this:
Intent i = new Intent(context, AlarmActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
So basically when the intent fires it starts the AlarmActivity. Inside that activity you could have it try what ever you are doing and if it fails call the setAlarm() again
You have two options: a Service, or set up an alarm with AlarmManager. Which one you pick will depend mostly how often do you want to retry. A minute? Use a service. An hour? A day? set up an alarm so you don't waste the phone resources keeping the service alive.
http://developer.android.com/reference/android/app/Service.html
http://developer.android.com/reference/android/app/AlarmManager.html
Write an Android Service