I have a function that reads the content of the Android clipboard every two seconds and communicates all changes with a remote server.
This works fine in the app is opened. But I need to be able to continue to log the clipboard changes after the app has been closed.
So I tried an IntentService but it doesn't appreciate long loops.
How can I run my infinite loop in the background?
I have a function that reads the content of the Android clipboard every two seconds and communicates all changes with a remote server.
Polling? You are doing it VERY wrong. You should use OnPrimaryClipChangedListener instead.
EDIT
communicates all changes with a remote server.
I just realised you are basically doing some bad things there and I am bit sceptical believing your users aware you literaly spying on them? Is your app in Google Play if so what's your app package id?
IntentService should be used to process single "request", from another application component, at time.
Use started service which should be more suitable for problem you describe. Started service runs until you manually stops it or until system gets out of resources and kill whole process.
Use START_STICKY as return from onStartCommand() method to automatically start it again when system kills it.
If you also start it in BroadcastReceiver with ACTION_BOOT_COMPLETED action service will be started after device boot.
Implement a Service and make it sticky by returning START_STICKY in onStartCommand (see Documentation):
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
Related
I have a location service which I want to run at all times when the app is in the foreground, or in the background, but to stop when the app is closed (removed from the app tray)
My solution has been to start the service using START_NOT_STICKY and this seems to work, but I'm concerned by what the service documentation says about this command
START_NOT_STICKY says that, after returning from onStartCreated(), if the process is killed with no remaining start commands to deliver, then the service will be stopped instead of restarted. This makes a lot more sense for services that are intended to only run while executing commands sent to them. For example, a service may be started every 15 minutes from an alarm to poll some network state. If it gets killed while doing that work, it would be best to just let it be stopped and get started the next time the alarm fires.
So it seems that Android may kill off services when memory is low, and if using START_NOT_STICKY the service will not be restarted.
I tried using START_STICKY but this keeps the service running even after the app is closed.
What can I do to keep the service running at all times while the app is in the foreground or background, and stop after being closed, but without worrying about Android terminating it while the app is running?
Code here if it matters:
#Override
public int onStartCommand(Intent intent, int flags, int startId){
if (intent != null) {
extras = intent.getExtras();
// takes the messenger object and makes it local so when the messagereceiver sends an intent here, it won't overwrite the extras object
// and get rid of the messenger. Otherwise, getting an update from the notification controls would null out the messenger object
if (intent.hasExtra("MESSENGER")) {
Timber.e("MESSENGER ");
messenger = (Messenger) extras.get("MESSENGER");
}
}
return START_NOT_STICKY;
}
What can I do to keep the service running at all times while the app is in the foreground or background, and stop after being closed, but without worrying about Android terminating it while the app is running?
I'm not sure what "app tray" you're referring to or what exactly you mean by "closed" (Android apps are not things that are "closed", per se.
But, from your description, I'd think you want to do something like:
Start your Service when the user starts your app and bind to while the activity is in the foreground
If your activity is paused (or stopped), unbind from the service and start a foreground notification to keep the service alive and the user aware that it's still running
Instead of trying to detect when the app is "closed", which you can't really do, attach a "cancel" action to the foreground notification so the user can cancel it whenever they want
If that doesn't solve your issue, please elaborate on your use case and why you want to do this. I or others may be able to provide more / better / alternate suggestions with more specifics about what you're actually ultimately trying to achieve.
Hope that helps!
My service is usually started by a BroadcastReceiver for RECEIVE_BOOT_COMPLETED, and is implemented with the START_STICKY flag as follows:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
So In many cases, when the user launches the app, the service would already be running in the background. My activity then binds to it to read information from the service.
However, when the user then destoys the activity (by terminating the app), my service that was already running is now destroyed as well, and it is then restarted via start_sticky. This causes some information that I keep in the service to be lost.
Is there a way to preserve my service instance, and just have my activities come and go, binding to it as needed?
There is no way to make sure a service (or any component of an app) will not be killed. If you have data that needs to be persisted you can use any of these techniques.
http://developer.android.com/guide/topics/data/data-storage.html
SharedPerferences is pretty easy to use.
Here is the section in the developer doc (and the link) that explains how apps are started and stopped by the system.
By default, every app runs in its own Linux process. Android starts
the process when any of the app's components need to be executed, then
shuts down the process when it's no longer needed or when the system
must recover memory for other apps.
http://developer.android.com/guide/components/fundamentals.html
Hi Everyone I want to create location tracking application in android which runs in background even after user terminates application by left swipe from recent application. till now i have used intent service started from main activity but it gets killed when i terminate application.
Any other idea to implement this?
I have tried by registering location updates and doing work of service in onLocation changed event. but listener also gets unregister after application exists.
I don't need full code but i need approach to do this.
Have you tried to track in a Service? Without reference to the activity. You have the start the service from the activity for the first time.
Note: A service isn't killed by swiping from recent apps, rather it is killed by the OS when more ram is required. To restart it after its killed you have to return START_STICKY to onStartCommand i.e:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Also, here you should register your LocationListener and perform whatever action you need.
And as always, remember to add permissions.
Can I run a background service Indefinitely ? Will android kill my service if i run it for indefinitely ? How Facebook android application keep running in background for a long time ?? please help me to know about it .
You can use for that these features:
1) Auto-restart service after reboot (Start intent after Reboot)
2) Sticky service mode (http://developer.android.com/reference/android/app/Service.html#START_STICKY)
These features both helps to leave your service started all time as possible.
Android will kill your service if it's running out of memory, but you can do a couple of things to recover from it.
The first thing you can try is to use foreground services, a foreground service is a high priority services that won't be killed unless is completely necessary (note that these services increase battery consumption). You can find an example here using compatibility with older devices, otherwise you only need to call startForeground inside your service.
Another thing you can do is to use some flags in your service to restart it when it gets killed by the OS. You can use 2 different flags (depending on which behaviour you want to reproduce).
START_STICKY will restart your service with an empty intent so everytime you have to recover the data you need to run your service.
START_REDELIVER_INTENT in this case your service will be restarted with the last intent information (it could be that you run your service several times with different information when you want different behaviour).
The flags can be used as follows:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Do your service work
return START_STICKY; //or return START_REDELIVER_INTENT;
}
Depending on what you need use one or another.
Hope it helps :)
There's no way to absolutely protect a Service from being killed.
If you return START_STICKY from onStartCommand(), then even if Service is killed, android will try its best to start it again, when resources are free.
I build an application that collects data about the battery. In order to collect this data I need my application to run on the background in order to be able to collect this data.
How can I do it?
You need to change your activities into Service
if you're against using a service for whatever reason you can have it thread off, then get the data when the user calls the application to the front.
you can use the onStart, onPause, onResume functions as well as making the application single instance so when you run it again, it mearly pulls it up from memory (assuming Android doesn't kill it for some reason).
You can use ongoing notification to prevent it from being killed in the background and moveTaskToBack.
But as pentium10 says, the intended way to handle background processes is through a service which gathers the data you are looking for, then when the activity comes back to the front, it gets the data from the service and displays it.
- #Override public int onStartCommand(Intent intent, int flags, int
startId) {
handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY; }