Android service restarting not working - android

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.

Related

Android: Service is stopped when clearing ram storage

I have coded a simple app in Android Studio. What it does is not important but it starts a Service with Context.startService(Intent i). Till now everything is allright BUT when I kill all tasks with my Task Manager of my phone the Service is killed, too and with it the notification ist creates! I don't understand why.
By the way: I used return START_STICKY at the end of my Service. And it has been started/sheduled by the Timer class with Timer.scheduleAtFixedRate(TimerTask task, int delay, int period). The Service has been started by my Main Application or by the BroadcastReceiver which received BOOT_COMPLETED. The timer has also not been canceled.
Hope you will pardon my english.
Services that are started with startService does not stop until an explicit call - stopService is done on that particular service. Another case when the service stops is when the phone needs more memory its stops the background services and applications. In your case, you are doing the exact same thing. Clicking on the kill all tasks clears the memory which is the exact thing that happens when phone is out of memory and wants more memory. In that case - services are stopped and sticky services are restarted. Now, how to handle the restart of the service properly, kindly search clearing memory stops services android and you will be shown a bunch of answers on stackoverflow !

Listen to app wake up event / schedule a wake up event

I'm trying to schedule event. For example, i'd like for something to happen 1 hour from now. For this i used handler postdelayed. Unfortunetly, this doesn't work as expected. I guess the reason is that android puts my app to some kind of sleep state, so the timer freezes at some point, and keeps counting from the point stopped when the device is back to use. This causes the event to occur at unknown time, greater than the time expected.
Now, i have two ways to solve this and i'd like to know how to implement each one:
Schedule to wake the device at a specific time and then excecute the event. I don't know how to schedule a wake up (and do it efficently).
Excecute the event as soon as my app wakes, if the time of execution has passed (i can use date and time to verify if the time passed). What i miss here is how to listen to wake up event.
And for my general knowledge about android sleep policy: Does android put services and activities to sleep automatically? how, if so, any messaging app keeps listening to new messages?
Thanks in advance for any help :)
You have to use Alarms,
Alarms give you a way to perform time-based operations outside the lifetime of your application.
android has 4 types of Alarms :
ELAPSED_REALTIME—Fires: the pending intent based on the amount of time since the device was booted, but doesn't wake up the device. The elapsed time includes any time during which the device was asleep.
ELAPSED_REALTIME_WAKEUP—Wakes: up the device and fires the pending intent after the specified length of time has elapsed since device boot.
RTC—Fires: the pending intent at the specified time but does not wake up the device.
RTC_WAKEUP—Wakes: up the device to fire the pending intent at the specified time.
Read this pages Alarms

Android Developer - Alarm manager vs service

I am making an app that needs to execute a function each hour even the app is closed.
First of all, I thought to create a service, but during my tests, I realise that android sometimes kills my service. So I was looking for another solution and I found AlarmManager. I have implemented it and it seems to work but I have the doubt if it will happen the same the service or it will run forever? (Until reboot of the mobile...)
Another question, it is necessary to create a new thread to execute the process in alarm manager or it runs directly in other thread?
I have implemented it and it seems to work but I have the doubt if it will happen the same the service or it will run forever? (Until reboot of the mobile...)
It will run until:
the device is rebooted, as you noted, or
the user uninstalls your app, or
you cancel the events yourself, or
the user goes into Settings, finds your app in the list of installed apps, taps on that entry, and clicks the Force Stop button
It's possible that alarms will need to be scheduled again after your app is upgraded (I forget...).
it is necessary to create a new thread to execute the process in alarm manager or it runs directly in other thread??
Unless the work you are going to do will take only a couple of milliseconds, you will want a background thread for it. That leads to two possible patterns:
If you are not using a _WAKEUP-style alarm, use a getService() PendingIntent to send control to an IntentService every hour
If you are using a _WAKEUP-style alarm, you will need to use a getBroadcast() PendingIntent, and have it either invoke your subclass of my WakefulIntentService, or you will need to manage a WakeLock yourself to keep the device awake while you do your bit of work
No, Android won't kill scheduled alarms and they got executed as planned unless app is replaced or device is rebooted. Use broadcast receivers for these events to reschedule Alarms. There's no way to prevent Force Stop as it kills all of your app components and threads totally.
That depends on what Alarm Manager do. If it sends a broadcast, the receiver limit is 10 second.
If it starts an Activity, Service or Intent Service, there is no limit. For Activity and Services you must finish or stop it and for Intent Services until the process is finished. Be aware that you can't have another thread inside Intent Service and you'r limited to code inside the OnHandleIntent.
Also you must consider device state. If it's sleep and you are using Wake Up flag receivers won't need a wake lock, but others do. It won't take long for device to go back to sleep.
Don't waste system resources with a service because Alarm Manager do what you want.

What is the idea behind creating Event Reminder app in android

I want to create Event Reminder App, I search and found that I need to use a service and broadcast receiver.
But it is not clear for me what is the role of each components ?
As I understand-but I am not sure- that the App needs an Activity that when starts, it runs the service ( which check the current time with times are stored persistently , for example in database !). when the two times match , the service create a broadcast, and our broadcast receiver receives it and create Alert.
My questions are:
Does this inception is correct ?
How to make the service running and always check the time ( do we need some infinite loop?!!)
thanks in advance,
Activities and Services can be killed off without notice anytime system decides it's low on resources. There is no guarantee that your Service would run all the time. Also, if phone is in sleep mode, your code stops executing.
So:
The premise is wrong, for the reasons stated above.
You cant guarantee that Service would be running all the time.
For your purpose you should be using AlarmManager. It is garanteed to call your code when alarm is triggered. Also important - AlarmManager survives device restarts.

Clarification of AlarmManager behavior in Android

I see all the examples of AlarmManager being set by an Activity.
My question is this:
If my application sets a recurring AlarmManager, does that persist even after the application that started is is closed and removed from memory?
If not, how do I start an AlarmManager at a lower level that is started by Android at boot up and if it ever fails or dies or throws an exception is restarted without the user having to do anything?
Lastly, if the action I wish for the BroadcastReceiver to undertake has no visual components, do I still have to create a separate Activity for it? In my case I want there to be a background uploader that wakes up and looks into a folder and if it sees files in that folder, sends them off to the server. I don't need any feedback to the user.
So, my ideal would be to have a magical, OS based AlarmManager that calls an IntentService which just handles the uploading, but I'm unclear on how to get such an AlarmManager running in the first place.
TIA
Yes, AFAIK the alarms "survive" and keeps getting triggered, even after the activity that registered them ends. But they don't survive a phone reboot.
If I understands your problem correctly, I think you can achieve what your looking for by creating a project with a broadcast receiver that listens for android.intent.action.BOOT_COMPLETED intents and then (re-)register a repeating alarm, which in turns starts a (Intent)Service to do the uploading.
You don't need an activity, but you probably would want one anyway, to let the user temporarily disable the upload mechanism by checking off a checkbox, or something. It would probably also be nice to let the user choose the frequency of your alarm, i.e. how often the service should be started and look for new files to upload. This would also be a good place to register your alarm for the first time.
I agree with Nicolai that you'd have 2 broadcast receivers in your application :
one that re-register the alarm on boot
one that starts your service when triggered by the alarm
You could still have an activity but it shouldn't be started by the alarm receiver (hence the service) : instead, maybe launch a notification as you start your service, with the user having the possibility to launch the activity from the expanded message of the notification.
maybe also think about setInexactRepeating (instead of setRepeating) for your alarm, as well as using a worker thread to handle the long uploads (in case the user wants to use your activity in the main thread at the same time).

Categories

Resources