I am new to Android, and I need some advices for start up.
I want to build an application, which will show up, when the user gets into some hot situation.
By hot situation I mean:
the GPS/cell coordinates are in known zone;
known Bluetooth device detected;
known Wi-Fi network detected;
weather info has change;
I see something running in background and when one of the clauses hit, it will trigger and open the app.
How to get started?
How do I make sure my app won't be shut down?
As I read somewhere that Android OS will terminate apps if memory out occurs or consumes too much, and my app would consume a lot, making repeated measures/checks to see if situation changed.
Regards,
Pentium10
You need to use a Service for the part of your application that runs in the background.
You might find the Application Fundamentals document in the Android Developer Documentation helpful. It says this about Services:
A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it.
In you case you might find the LocationManager Service helpful. It is a system Service which will you can use to notify your application based on GPS position.
However, I think you'll have to write your own Services to monitor Wi-fi, Bluetooth and weather.
You can use the AlarmManager Service to get your Service to perform particular tasks at certain intervals.
It depends on how & where you want to deploy your application. In my experience it boils down to
you create an application for a specific use case where battery drain matters less than accurate results (showcase situations, prototyping, ...)
you want to distribute the application to users.
In case 1) just create one service that aggressively polls the sensors / web services. Use the AlarmManager to send a REFRESH intent (AlarmService.setRepeating(...) ).
That REFRESH intent will restart the synchronization service everytime, even if it was killed by the system. onStart() will be called everytime the REFRESH intent is emitted. You can do heavyweight setup logic in onCreate() as this will be called everytime the service is created after it was destroyed. WARNING: This will possibly drain the battery very quickly.
In case 2) I would create several services and let the user configure different polling intervals for each service to limit battery drain. I can see for example that bluetooth should be polled more regulary than GPS as it is more likely that a bluetooth device suddenly appears than a user moving extremely fast.
Weather sounds extremely expensive (network lookup, possibly triggering a network connection!)
Please do not try to be too persistent with your app in case 2). It usually makes a lot of sense for a phone to kill memory / power draining services.
Related
I would like to make an app that always works in the background (from boot up), which sends GPS coordinates to a server. This app should ALWAYS be active and should never close.
Should I use the services? I would like to use UDP sockets to send coordinates but I accept alternatives. I would also like to avoid using the google API.
Thanks a lot :)
If your app need to run in the background , you need Service and you need to make it a foreground service which means you need to show a notification to the user as long as your application is running.
To open app on device boot, from Android O, its not allowed. You will get an IllegalStateException.
The main reason for this is to prevent exactly what you are trying to achieve.
Its not good to keep running an app in the background and its especially bad to keep tracking users GPS coordinates and send it to the server.
Because it will drain the battery very soon.
However it is possible to keep a foreground service running which can take the GPS coordinates and send it to the server. But for that user has to open your App first.
Please refer to
https://developer.android.com/about/versions/oreo/background#services
Other alternative is to use JobIntentService which will schedule your tasks in smart ways to avoid draining users battery and data.
Regarding UDP sockets , it depends on your backend.
The app needs an underlying feature that picks up locations and sends them to a server. This must happen regularly (approx every 1-5mins) but most importantly it must happen all the time, never stopping, protected against the OS shutting processes down to reclaim memory, and when the app itself is not running.
The following solutions have been suggested to me. I'm familiar with handling Android locations, the issue here is to ensure they continue, even if the app is not in memory, and to persist through memory reclaims.
SERVICE. Use a service to collect location events and handle them. Use the boot and screen-on broadcasts to ensure the service is always running (and possibly also increase the service priority to protect from memory reclaims).
ALARMS. I gather these can be shut down when memory is short. How would I protect against that? This seems an ugly solution as the locations will arrive on a schedule anyway, so it seems unnecessary to have another time-based component.
LOCATIONS VIA BROADCAST. Locations delivered via a broadcast intent would mean I can then handle the location events in a broadcast receiver. Will these location alerts continue indefinitely? Will anything other than device shutdown or the app turning them off cause them to stop?
What's the most durable approach?
This must happen regularly (approx every 1-5mins) but most importantly it must happen all the time, never stopping, protected against the OS shutting processes down to reclaim memory, and when the app itself is not running.
This is not strictly possible, on a variety of fronts.
Let's take them one piece at a time:
This must happen regularly (approx every 1-5mins)
You may not be able to get locations, period, let alone every 1-5 minutes. The user might have all location providers disabled. The user might have the device in airplane mode. The user might be in a large building (blocking GPS) with poor connectivity (making the network provider unreliable).
never stopping
The user can always get rid of you via the Manage Services screen in Settings or a task killer. If they do so, particularly on Android 3.1+, your app will never run again for any reason until the user starts an activity of yours (e.g., via the launcher). The user could also uninstall your app, of course.
protected against the OS shutting processes down to reclaim memory
You cannot guarantee against this. You can reduce the odds, but that is it.
Now, let's look at your various solutions:
Use a service to collect location events and handle them.
From the way you phrase this (and subsequent sentences), you mean an everlasting service, one that is designed to run 24x7. By definition, this means that your app is running, which violates one of your rules. Assuming you relax this rule, this solution massively increases the odds that the user will get rid of your service, and it increases the odds that Android will get rid of your service. You can minimize the latter by use of startForeground().
ALARMS. I gather these can be shut down when memory is short.
Not that I am aware of. However, if the user gets rid of you, your alarms will be removed.
This seems an ugly solution as the locations will arrive on a schedule anyway
No, they will not. The time parameter on requestLocationUpdates() does not mean that "locations will arrive on a schedule anyway".
Locations delivered via a broadcast intent would mean I can then handle the location events in a broadcast receiver.
No, you cannot. You have indicated that part of your work will be to send this data to a server. You cannot reliably do that on the main application thread, as it may take too long. A getService() PendingIntent, pointing to an IntentService would be more reliable.
Will these location alerts continue indefinitely?
No. See below.
Will anything other than device shutdown or the app turning them off cause them to stop?
The user can get rid of your app (uninstall, task killer, Manage Services). The user can disable location providers. The user may enter an area where the location cannot be determined. Etc.
Also, the device may fall asleep, AFAIK. It's possible the system keeps a WakeLock for the duration of your registered request for updates. It's even possible that the system will use AlarmManager internally to arrange to wake itself up on your supplied period, so it does not have to keep the device awake continuously. However, you will want to test this thoroughly.
What's the most durable approach?
If the concerns in my previous paragraph are handled by the OS, your third option is probably the most robust. Use startForeground() in your IntentService() and call stopForeground() just before exiting onHandleIntent() -- even short-lived services started by AlarmManager may get killed off due to low memory, much to my surprise.
That being said, your desired behavior seems like it may consume more battery life than the user might want. Please allow the user to control the polling period, including an option for "never poll, I'll update things manually".
I've created an android app that is so far working quite well. It contains a local service which is responsible for getting the users location every couple of minutes and relaying that via UDP to a collection server which is in turned displayed on a web application map.
The app needs to be constantly running unless the user explicitly signs out of the application. Currently, it seems the OS is shutting down the service and restarting it as needed. I can see this because normally it would report its location consistently every 2 minutes. Instead, there are gaps in these intervals.
So I'm looking for some advice on how I can write a service which (at the battery's expense unfortunately) can stay running always and pool the location service just enough to send accurate fixes at a 2 minute interval.
I have a well working code base so far, so if demonstrating where I currently am with code would help, don't hesitate to ask.
Thanks in advance to those that lend a hand.
Your best bet is to use the AlarmManager to wake up every two minutes, do some processing and quickly go back to sleep.
If you think you're hardcore, you could even use a wake lock, but that will keep the phone's CPU turned on persistently without mercy. You don't want that.
My company has, in essence, undertaken a project to replace some of its pagers with stock smartphones running Android. As long as they are signed in, the device should be listening on a particular socket to receive "pages" from a server. My naive implementation was to create a foreground service that 1) kicked off a listening thread, and 2) holds a PARTIAL_WAKE_LOCK.
This works fine unless the device has a long period of inactivity, 1+ hours. Then, it appears that the OS shuts down my app's process, understandably believing it to be not in use.
I completely understand their reasons for doing so, but I'm wondering if I can somehow get around this restriction. Are there ways to signal Android that my process really is important enough to keep alive/the device awake? I learned both Java and the Android API for this project, so there are plenty of areas where my knowledge is incomplete.
Failing that, given the description of my business needs, how would you suggest implementing this functionality? While the user is signed in to our custom app, the device should always be listening.
Thanks to everyone for reading this question.
The OS won't kill your process if you are using Service.startForground(). This is what things like music playback use, and you wouldn't want those to be killed after some amount of time.
That said, for this kind of thing you generally wouldn't need to make your service foreground -- when the system does kill your process because it has been sitting around or needs the memory, it still knows the service wants to remaining running so will restart the service shortly after that. This is how Google's own services work, they have one .apk that has a background service running that keeps a network connection open to a Google service which reports back when interesting things should be done like sync new e-mail, retrieve and deliver a C2DM Intent, etc.
Also you should not hold a wake lock during all of that time. You will kill the battery, especially on some devices like those with Samsung's Hummingbird processor. The right way to do this is to just leave the socket open and let the device fall asleep. If data is delivered to the socket, the CPU will wake up to deliver that data and at that point you should acquire a partial wake lock just for the time you need to read and process the data.
What you describe sounds like a job for Android Cloud to Device Messaging Framework.
It's currently not completely open but there is a signup link on that page. I signed up and was accepted within 20 minutes of my application. Worth a look IMO.
I'm developing an app that checks several conditions during an incoming phone call. The main parts of the app are a BroadcastReceiver listening for Intents related to the phone's status and a local Service checking the conditions.
At the moment the service is started each time an incoming call is detected and is stopped when the phone status changed back to idle.
Now I'm wondering if this procedure is correct and whether it is reasonable to start and stop the service related to the phone's status. Or would it be better to let the service run regardless of the phone's status and bind/unbind to/from it when needed.
Are there any performance issues I would have to think about? Perhaps it is more expensive to start/stop a service than letting it run and communicate with it. Are there any best practices out there regarding the implementation of services?
Or would it be better to let the
service run regardless of the phone's
status and bind/unbind to/from it when
needed.
Please don't. It will just take up RAM for no good reason. It is everlasting services like this that cause users to attack developers with task killers.
Are there any best practices out there
regarding the implementation of
services?
Here are two of my posts on the subject, for what they're worth.