I'm looking to build something similar to Google's field trip application. The key attributes that I'm looking to prove out are:
A background "job" that runs every X minutes and checks the user's location and make a webservice call(this question doesn't really concern the location part)
The job should run even if the user exits the main application.
The background job should automatically start up after the device reboots.
After a reboot the application should not show up on the "recent/history" screen
My reading has brought me to a number of different classes/APIs from broadcast reciever of on boot, to regular services, to alarm manager, etc. It seems there are multiple ways this could be made to work, I'm curious what the community recommends as a high level approach?
You would definitely want to use a broadcast manager to get the boot event.
As far as polling for location goes, it sounds like you would want to use a Service and start it once you received the boot event.
Services
You could then use an event bus like Otto to communicate your events to wherever you need.
As far as the timing goes you could use a job manager to run things at various intervals, or just simply create a runnable and have it run as often as you like. As long as you keep it in the service, you should be able to control the length that it will run just fine. Regardless of whether or not the app is closed.
I think you may divide your solution into two parts :
Starting the app or the service after the device re-boot process completed by defining a Broadcast receiver that has the following action :
And on the "onReceive" method of the broadcast "do your task " start the service that listen to the location service updates.
For the part of listening to the location updated every x minutes, you would better use the alarm manager to "wake up" the service every x minutes, and every service sets the alarm for the next call.
Related
this scenario is very common according to the Android documentation but still I don't find a straight solution neither there nor anywhere on the net.
So I have a service that should do something like this:
Register a LocationListener to receive the user location
Once the LocationListener is called - stop listening for a 5 minutes
After 5 minutes start listening again and loop from 1
This is the recommended way to save battery power while listening for the user location.
As a service I have a major problem with step 3.
The only way I found to "wait" for 5 minutes is to schedule a java.util.Timer to execute a TimerTask in 5 minutes and this TimerTask should register the LocationListneres again.
However this does not work because of:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Which is also expected because requestLocationUpdates should be called from a "main" thread.
Ok .. nice... but I don't have a Main thread. I don't have an activity. From the TimerTask I can't send an intent to the service to register my listeners back.
How can I ask my own service to register my listeners again?
This is the recommended way to save battery power while listening for the user location.
Really? The only way that's a good pattern is if you are using AlarmManager for the five-minute delay, so the device falls asleep in between location checks.
The only way I found to "wait" for 5 minutes is to schedule a java.util.Timer to execute a TimerTask in 5 minutes and this TimerTask should register the LocationListneres again.
And that would be a horrible use of battery, because it would mean you would need to keep the device powered on constantly, not allowing it to go to sleep.
I don't have a Main thread
Yes, you do. All processes have a main application thread. onCreate(), onStartCommand(), etc. of a service are called on the main application thread.
I don't have an activity.
Then you better write one, as your app will not work on Android 3.1+ without it. Your app will not run until a user launches one of your activities on Android 3.1+.
How can I ask my own service to register my listeners again?
What you are trying to accomplish is a rather complex problem. Not only do you need to arrange for the device to fall asleep and wake back up again, but you also need to deal with lots of edge cases (e.g., what if no location is available, because the device is in airplane mode or is underground or something?).
I wrote LocationPoller to handle your use case, and another developer forked it to create a more feature-rich implementation.
Whether you use one of these directly or simply examine their implementation, they should be useful to help you understand how to solve this problem. All of the details, though, are well beyond the scope of a StackOverflow answer -- it would take several pages in a book to explain it all.
You can specify the parameter in requeestLocationUpdates() to make it run after a certain time.
I need to run a background service in Android mobile which runs 24*7, And on Start & On mobile low battery and Hit a webservice every 1hr. Can you please suggest me any approach. I tried reading few articles but did not get any idea. I know here I need to paste some code after trying something. But I did not get any clue. Please let me know how to approach?
You will probably need to use the method startForeground(int id, Notification notification) to prevent the system from killing your Service as stated here:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
Then you would need some kind of scheduled task to run every hour. Something like a ScheduledThreadPoolExecutor is ideal for this purpose, using the method scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit).
The task that needs to be done each hour must be implemented as a Runnable and submitted to your ScheduledThreadPoolExecutor:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( 1 );
executor.scheduleAtFixedRate( new MyRunnableTask(), 0, 1, TimeUnit.HOURS );
The Runnable task should be something like:
private class MyRunnableTask implements Runnable {
public void run() {
//Do what needs to be done.
}
I need to run a background service in Android mobile which runs 24*7
Please don't. For starters, it is not possible.
Users complain loudly and often about services that "run 24*7", because the services are tying up system resources (e.g., RAM) for no value. As a result, between third-party task killers and Force Stop options in Settings, users get rid of such services. When they do, particularly on Android 3.1+, your application will not run again, ever until the user manually launches an activity of yours from the launcher.
Android itself will get rid of such services on its own, because too many developers are too sloppy with their service management.
And on Start & On mobile low battery and Hit a webservice every 1hr.
Based on this list, you do not need "a background service in Android mobile which runs 24*7". You need to do work:
when the device starts up
when the device's battery is low
every hour
You can find out when the device starts up by the ACTION_BOOT_COMPLETED broadcast Intent. You can find out when the device's battery is low via the ACTION_BATTERY_LOW broadcast Intent. You can find out when time elapses via AlarmManager, where you establish your own alarm schedule (e.g., every hour).
All three of these triggers should call startService() on an IntentService. The IntentService will allow you to "Hit a Webservice" via its built-in background thread. And, the IntentService goes away when that work is complete, so you are not taking up memory all of the time.
And, if you want to wake up the device out of sleep mode for the every-hour condition, you will probably need to use something like my WakefulIntentService, as otherwise the device may fall back asleep while you are trying to "Hit a Webservice".
This way, your service is only running and taking up resources while it is actively delivering value to the user. It is not running and taking up resources when it is simply waiting for some other event to occur (e.g., the next 59 minutes).
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.
I am coding an android application that gets the user position every 5 minutes, stores it in the database and sends it to a server.
I have read many ways of doing it, I was going to do the following:
User starts the application
The main UI activity starts a service.
The service runs in background and keeps turning on and off the gps, and creating new
threads that will save to database,and send the data to the server.
But I have seen that it can be done with a "Remote service" (http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html) or with an AlarmManager that schedules starting this service every 5 minutes.
The service will need to be running always: it is important that after every interval (5 minutes), it is executed.
I think I need some clarity here.
Thank you for your help,
I am coding an android application that gets the user position every 5 minutes, stores it in the database and sends it to a server.
Please allow the user to choose the location provider. Not everybody has GPS on their device. Not everybody has GPS enabled. And, not everybody will want the power hit of GPS being turned on every five minutes.
Please allow the user to choose the polling period, including "never poll -- I'll refresh the information manually from the activity". Also, please honor the background data setting (deprecated as of ICS).
I think I need some clarity here.
If the polling is supposed to go on even if the activity is not in the foreground, use AlarmManager. However, most recipes for using AlarmManager will have the real work (in your case, GPS fix and network I/O) be handled by an IntentService. This will not work in your case, because GPS is asynchronous -- you cannot just get a fix whenever you feel like it. It will take a long time, possibly forever, to get a fix, so you have to deal with the delay and eventually timing out the operation. Writing a Service to do this is possible, but tricky, particularly if you are aiming to collect this information even if the device falls asleep.
If, however, the polling is only supposed to go on while the activity is in the foreground and the device is on, I wouldn't bother with a Service at all. Just have the activity use postDelayed() to set up an every-five-minutes scheduled bit of code to run, then have it do the work.
I have a service that will monitor location changes daily. What I know so far that to start a service at boot, I have to follow the linked tutorial. This way I can get the service started at boot, but to save battery I need it only between 9am-9pm.
Question is pretty simple, so I will repeat:
How can I ensure a service is started at 9am and stopped 9pm every day?
Use AlarmManager to set two alarms, each with a PendingIntent that will call startService() on your service, but with distinct action strings ('start', 'stop'). When onStart() of your service detects the 'stop' action Intent, it arranges for an orderly shutdown (e.g., stopSelf()).
This will fail if the user applies a task manager to you in Android 2.1 or earlier, since the technique they tend to use will wipe out your alarms (in addition to killing the service). In that case, the user is presumably voting for your service to not run, so you should try to accommodate the user's wishes.
CommonsWare is right. This is the best way.
You are writing an application and you had better not to change anything out of the application. If you want to add a system service(on boot started service), you need to modify the BSP and add your service to systemserver.java. It's not recommended.CommonsWare's suggestion can do this work.
As you said about the activity, you can start the activicy when you receive the boot broadcast. Then do what your want.....