I don't know why, but my Service ( started with startService(Intent...) ) keeps closing after a while. I want my Service to check every 2 minutes the position with WiFiSLAM, therefore a TimerTask is running in the Service. I realized that my Service is shutting down after the App is closed (onDestroy) and the screen turned off.
I've read about the WakeLock and tried this:
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
wakeLock.acquire();
But it still does not work. I don't know what to do. I just want to have my Wifi Positioning Framework to update the position in the background every two minutes.
I also set the return value of onStartCommand() to START_STICKY. Maybe it is running in the background, but I can't see the Logs in the LogCat when it is running for a while, which gives me signals that the indoorLocationManager is still catching new positions.
Someone has an idea?
Android automatically kills applications running in background for long periods (between 30 minutes and 1 hour).
The only way to prevent this is setting your service as foreground service.
To do that, you use the following:
startForeground(messgae, notification);
This will show a permanente notification informing the user that your service is running.
Other option, is to use AlarmManager to start an IntentService every 2 minutes.
Regards.
I have in the past had the ame problem, and you may not want to do this, however it does work for me. I set up 2 Services, the main worker, and a helper. The helper, every so often will make sure the worker is running, and the worker will ensure that the helper stays running. In this example, if one of them happens to get killed by the system, it will be relaunched by the other. I have never had both of them die at the same time.
Again, this is my solution that may not be something that you would like to do.
One solution is to use an alarm that launches you service at two minute intervals, or whatever you decide. However doing this will drain the battery, so keep that in mind.
Related
I am working on an application which triggers an action (say toast message) every 10 minutes after the screen is ON and stops the action after the screen is OFF.
I have used TimerTask for this purpose.
Shall I start using AlaramManager instead of TimerTask or shall I keep using TimerTask ?
I know the difference between the two but can't figure out which to use.
Cant' agree with the nikis' answer
Timer and AlarmManager are solutions addressed to satisfy different needs.
Timer is still a "task" that means this is a thread of your application that means that some component of your application must be running on device to keep timer alive.
If you set timer for 10 minutes events - you can't be sure if your application will not be disposed by system in some moment. If device will be turned into the sleep mode your timer can be stopped. To prevent behavior like that you have to use PowerLock's and drain battery
AlarmManager is system service (runs outside your application) that means that the pending intent will be sent even if your application is killed after setting the alarm.
Some examples:
You have to blink some "led" on the view every 1 s - use Timer - you need it only when application is in foreground, there are short intervals - no point in using AlarmManager for task like that.
You have run some task once after 10 s - Handler.postDelay(); will be the best solution for that, and the job will be done on main thread (UI).
You have to check every 10 minutes if there is some new content on device that you are supposed to push to the server - use AlarmManager - your application does not need to be alive all the time, just let system to start job you want every 10 minutes - that's all.
In most cases you should definitely use AlarmManager, because (from the docs):
The AlarmManager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing. This guarantees that the phone will not sleep until you have finished handling the broadcast. Once onReceive() returns, the AlarmManager releases this wake lock. This means that the phone will in some cases sleep as soon as your onReceive() method completes.
Although you don't need to fire any event while screen is off, AlarmManager still saves the battery by grouping alarms, when you use setInexactRepeating (but this is not important for you, because your interval is 10 minutes). And moreover, it can fire an event is app is not running. I vote for AlarmManager, because it's good practice, but considering your conditions, you can leave Timertask.
BTW, you can also use Handler, which I believe will be the best choice.
Ive created a timer which counts down and when it reaches 3 it starts vibrating stronger and stronger until at 0 it vibrates fully.
My problem is that if the user turns off the screen the timer becomes unstable, i.e. counting down unpredictably or not at all. After searching around for a while I found that the solution probably is to use the AlarmManager, however this seems very complex for such a simple task.
The timer should be tied to the activity and if set, a notification indicating the time left should also be fired.
Any ideas?
There are a few options that you could consider to do what you're asking, and each one woudl depend on your specific circumstance and what you really want to achieve. A Service, an IntentService (Service subclass), AlarmManager, or a (partial) WakeLock (and maybe some more creative solutions that I'm missing).
I think the easiest thing out of the gate is to use a Partial WakeLock. It's dead simple, and is useful if you want a process to run in your activity even when the screen is off. You have to use it sparingly though, as it will chew up battery life (which is why activities pause when the screen is off).
To use a WakeLock:
Add the permission in your manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
In your activity, start the WakeLock when you need it
PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLockTag");
wakeLock.acquire();
When you're done with the wakelock (i.e. don't need to run the process any more), release it:
wakeLock.release();
It's clear that timer will be unstable if you implement it in activity. It results from lifecycle of activity. Main activity element it's GUI thread which is not the best place to implements logical elements.
You should use alarm manager or implement your own service to manage action which will properly work in the background. You have problem because when you switch your screen of your app is paused and until you'll restart it you haven't full control about the action inside activity.
I'm a fan of programming using brain, so I give advices, not clear code. But I hope that it will help.
I have build a service to broadcast a timer data to various activities. Usually it runs ok without problems, but there are ocassions when android restarting it does not work as expected.
It has also three Broadcast receivers:
1 - Screen off event: in order to stop broadcasting timer data and setting an alarm in alarmanager for when the service ends, so I will be able to play end notifications for the users to attend.
2 - Screen on event: in order to continue broadcasting the timer data. I also cancel any preiously alarm pending.
3 - A receiver for alarms. This usually fires when screen is off, as explained in 1.
My service is started with startForeground and return START_REDELIVER_INTENT. AS the start intent has inicial timer date, I can recreate service status without problem. Broadcast alarm receiver and onStartCommand share the same handle intent routine to start or continue the service.
All this works perfect. For short timer ( < 30 min ) I dont find any problem. The screen can be on, off, change same times from on to off and from off to on. Also the activity can be in front or in back. I have toying with those all possible states. In all cases, my service and activity runs ok.
My problems comes when some timer are longer ( > 30 min , usually I set up for 35 min). There are sometimes that maybe due to memory reason Android kill me service. That is ok, as I understand Android does this in order to improve user experience. The problem is that when I goes to 'settings/application/services' I can see my service in 'restarting' state. I suspect this mean Android has not launched it yet and it is been sheduled. It show that state for long time (I have not had patient to say if it changes for more that other half hour....)
The problem is that when in that state, that can long for ever (I have been looking into it and the service is never started), the timer (in my watch) reach the timeout, the alarmmanager launch my intent, but as my service is not started yet and the broadcast not registered, I cann't do staff for time outs (playing notifications). So the user does not known the service timer has ended and it is a heavy problem.
It is very courious. As the service is killed in almost any run passed 30 min, while other services are not killed.
My question is: what exactly is it happening? How can I correctly handle this situation in order to detect alarms been fired correctly, or more to the point: how can I force my service to be restarted correctly?
For adding some help data:
My service does have very little memory compare to others, and also does not run long operations, it only uses handler.postdelayed("sendUpdatesToUI",250) when screen is on, and nothing when screen is off, only waiting for alarmmanager to send time out intent.
When time is reached, and user opens the activity, it received the timer data broadcast intent from service and as it see time is reached, then it stops the service.
I understand and accept user can kill the service when he wants, and I accept that. The problem here is not the user, but Android restarting the service.
When service killed, onDestroy is not invoked.
Using 2.3.4 version.
After lot of investigation I found the solution to my problem. It is all about startForeGround function. I was using:
startForeground(0,not);
while this looks good and it found in lot of examples around the web, the correct way to do it is not using 0, but any other random value:
startForeground(2765, not),
This solve the problem.
So in my "Home" activity in my Android app, I have a non-deamon thread that is constantly running in the background that checks a blog for new posts every 30 minutes or so to fire notifications. It works fine when I make the thread sleep just for a few seconds for testing purposes to make sure that it is indeed working in the background, but in the actual phone, when the event is supposed to fire after half an hour, it just doesn't. So my question is, when I do *Thread.sleep(30_MINUTES)* does the android system kill it or something for being an inactive thread for too long? Does android kill sleepy threads?
Why don't you try AlarmManager to fire your polling code every 30 minutes ? Once the polling is done re-schedule if for the next 30 minutes. AlarmManager is much more reliable than making the threads to sleep
OK, so the problem was solved. What was causing the problem was that in Android when you put a Thread to sleep for let's say 30 minutes, when the device goes to sleep (the screen turns off after inactivity on the phone) the CPU goes into a so called "deep sleep state" which causes the thread's counter -that wakes the thread wake up- to pause while the screen is off. This means that when you say Thread.sleep(500000) for example, those 500000 milliseconds are counted only when the phone is awake. The solution is to use AlarmManager and a BroadcastReceiver to run the code periodically.
Here's a simple guide on how to use AlarmManager with a BroadcastReceiver: http://justcallmebrian.com/?p=129
I am not sure what you are doing in your coding but definitely android system does not kill a thread on its own whether sleepy or not doesnt matter.
What exactly is happening during this time? I believe the only situation in which what you're describing (using the technique you describe) would work reliably is if both (a) your activity (or another activity or service that runs in the same process) is the foreground activity for the entire life of the thread and (b) there's a wakelock preventing the CPU from sleeping.
Android may not kill individual threads, but it absolutely can and will kill processes based on the process lifecycle.
I am doing a Battery Consuming research on the Android phone. I want to run a Battery Check every 10 min till the battery totally dies. I have been having problems to make it work.
At my first try, I use a timer in a service class, and schedule the battery check every 10 mins. But soon I found that the service got paused when the screen goes off.
Then I try to use AlarmService, I use a alarm call to wake my service every 10 mins and to check the battery level and save the data to a file on the sdcard. It works with the screen off. However, I only got data of 9 hours...it seems that the AlarmService stop at some point after several hours. I don't know why it is like this, has the system killed it for memory issues?
So my question is, has anyone written some service to run (like forever) in the background before? How do you do it and I'd appreciate very much for a sample code?
I am currently reading some posts saying that there's a partial wake lock I can use to keep the service alive.. is this the correct way to do it?
Thanks a lot and I hope I can get some useful answers here.
At my first try, I use a timer in a
service class, and schedule the
battery check every 10 mins. But soon
I found that the service got paused
when the screen goes off.
You probably did not hold a WakeLock, so the device fell asleep.
it seems that the AlarmService stop at
some point after several hours
I rather doubt it.
So my question is, has anyone written
some service to run (like forever) in
the background before?
It is not possible to create a service that will run forever. It should be possible to create a scheduled task via AlarmManager that will be invoked "forever".
I am currently reading some posts
saying that there's a partial wake
lock I can use to keep the service
alive.. is this the correct way to do
it?
I'm not sure what "it" is. But, if you want to keep the device awake -- whether for your first approach or just while you are doing work triggered by an AlarmManager -- you need to hold a WakeLock.
Here is a project that does almost exactly what you describe for the AlarmManager, minus checking the battery level, but using a WakefulIntentService to ensure the device stays awake. If you cannot get this code to run until the battery shuts down, join the cw-android Google Group and report your findings, and I'll take a look at it.
http://github.com/commonsguy/cw-advandroid/tree/master/SystemServices/Alarm/