I noted that when I close my app definitively, the method runInBackGround of the class MultiplyTask stops working. It works when the activity is in the phase STOP or PAUSE, but when I close my app, the method finishes ( it's a loop created with a cycle while(true) {...} ).
How can for example Whatsapp send notifications though it's closed? I want to create a similar thing. Thanks!
When the app is closed, all code will stop running. If you are looking to execute while the app is open and continue executing code while the app is closed, you will want to look into using a Service.
Take a thorough look at the Service documentation and it will hopefully be what you are looking for.
Services are also killed when your app is closed, but using the START_STICKY return value you can make sure your service is restarted upon termination.
EDIT WITH MORE INFORMATION:
<service
android:name="MyService" />
Add the above to your AndroidManifest.xml
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// This is where you would place your code that you want in the background
// Putting your while loop here will make sure it runs when the app is closed
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
Create a new class with the above code.
Intent i= new Intent(context, MyService.class);
startService(i);
Call this code from your launcher Activity to start the service when the app is launched.
Hope this helps!
Asynctask is ideal for short operation which are needed to be performed in the background. Usually Asyntask is implemented as sub class of activity which is destroyed when app is close. Also It communicates with the UI thread at some points ... so It needs the activity to be in memory... For long running operation, Service is better. Some Apps notify user even when they are not running. In fact they have one or more services running in background. You can see those in your phone setting->apps menu.
Study this for more information about services.
Related
My Android application starts a local foreground service (in the same process as my activity). The service have to stay alive, even if the system destroys the activity due low memory.
Next time a user starts the app, I need to check whether the service is running or not.
I tried to store state in public static boolean Started = false; flag in service class (I know that it is bad practice).
My activity starts in the process where service is running. I thought, that static constructor is called ones. So, I would be able to check this flag in activity. However, static data is reinitialized to defaults.
Could any one give me a cue about this behavior?
here is just an example how I restart the service when apps come forground
public void storeLastLocation() {
if (!isStoreLocationActive){
Log.d("IQ MA", "storeLastLocation() called");
String access_token = Configs.access_token;
Intent intent = new Intent(MainActivity.this, StoreLocationService.class);
intent.putExtra("access_token", access_token);
stopService(intent);
startService(intent);
isStoreLocationActive = true;
}
}
then store boolean on service is running
So i want to do certain things always run in background. I've read that to do that i need to use android.app.Service, so i could not find anything that explain how to do this with libgdx so i did this.
on the AndroidLauncher I added this line
startService(new Intent(getBaseContext(),MyServices.class));
MyServices.class extends Service and on onStartCommand() i added a new thread that has a infinite loop, like this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(){
private long startTime;
public void run() {
while(true){
if(System.currentTimeMillis() - startTime >= 1000){
startTime = System.currentTimeMillis();
System.out.println("running");
}
}
};
}.start();
return START_STICKY;
}
The app keeps printing "running" every second even when the app is not running, but I feel like this is not the correct way to do this, can someone please enlighten me? Thanks
Same for me, I am trying to implement :
this is what you are looking for, Bound Service
Edit:
Add service to your Androidmanifest.xml file
Bind Service to Activity or Start service
bind service mean if activity stop also service stop, example a music player,
starting service, will not stop, like a service where it give notifications even if application is not running.
There is also a permission for on boot, you need to implement so that the service start when your phone boot up.
happy coding.
Hello I am running a background service to check in my server if there is a new data.
But if I kill the App, the background service also dies.
If I run the background service on it;s on process, the system kill it after it has run a couple times.
Manifest
<service
android:name=".backgroundSerive"
android:enabled="true"
android:exported="false"/>
Option 2
<service
android:name=".backgroundSerive"
android:process=":my_process"
android:enabled="true"
android:exported="false"/>
MainAActivity - Starting the service
Intent i = new Intent(this, backgroundSerive.class );
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(i);
Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...start runnable
return START_STICKY;
}
I try both option, The service keeps getting killed.
Any advice. To make my server always run.
thank you
You need to call startForeground() from within the service, to lower the chance of Android actually killing it. Please check out this sample for an example implementation.
startForeground function sends the service to foreground, so android system considers this operation as a foreground task. Which is very less likely to be killed.
If you have choosen the services destroy action as START_STICKY it would get destroyed but right after it destroyed it should be reinitialized with a null intent.
You may consider using Alarm for such event.
Since alarms are running in an internal process they reduce the app overhead, yet they provide recurring checks.
I have added Google Now search within my application. The way it works is, the user types something in the EditText object and oonce they press the button, this intent runs -
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
String term = searchInput.getText().toString();
intent.putExtra(SearchManager.QUERY, term);
startActivity(intent);
However I am having issues killing the service after the intent has been launched.
calling finish();after the intent will not work unless I am directing the intent to a different class itself.
Here's a video preview fo what I mean, you can clearly see I am pressing home to close the app but when I reopen it . It opens to the Google Now app. But when pressing back, it stops. How exactly can I get the intent to stop after I press the home key?
And my app is a dialogue type app so I have excluded it from the recent menu because of allot of reasons. Everywhere else the app kills itself as soon as the user exits it but here the service keeps running.
Video - Video Preview
I have also tried many questions answers, have researched but nothing has helped so far. I may be doing something wrong. Could someone kindly help me out here, thank you very much! :)
A started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. So, the service must stop itself by calling stopSelf() or another component can stop it by calling stopService().
use stopSelf() upon compleetion of task assigned to service.
And if you want to finishs ervice when application finishes, then in onDestroy(), call stopService() after checking whether its running or not, such method can be used:
public static boolean isMyServiceRunning(Class<?> serviceClass, Activity pActivity) {
ActivityManager manager = (ActivityManager) pActivity.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
to stop service from activity use below code:
stopService(new Intent(yourMainActivity.this,yourIntentService.class));
or you can write condition in service to stop itself like below:
if(check your condition here)
stopSelf();
You don't have to stop an IntentService - it will terminate itself when it has no more work to do.
It runs on separate worker thread.
Multiple intents are queued on the same worker thread.
So even if your Activity was destroyed from where this service was started it will continue performing its tasks until all the queued ones are complete and after completion it is automatically terminated.
Caution: It's important that your application stops its services when it's done working, to avoid wasting system resources and consuming battery power. If necessary, other components can stop the service by calling stopService(). Even if you enable binding for the service, you must always stop the service yourself if it ever received a call to onStartCommand().
stopService() : Request that a given application service be stopped. If the service is not running, nothing happens. Otherwise it is stopped. Note that calls to startService() are not counted -- this stops the service no matter how many times it was started.
Note: that if a stopped service still has ServiceConnection objects bound to it with the BIND_AUTO_CREATE set, it will not be destroyed until all of these bindings are removed.
I am having difficulties trying to handle service behaviour in such case.
Basically I have a service running on a separate process that needs to issue httprequests every certain time whenever the app is closed, then write something into preferences or throw a notification.
The logic works fine. The problem I'm having is that I cannot find a way to properly stop/disable that service whenever the app is running, aswell as start it again when the app is being finished or put into background.
I've tried stopping it at #onResume()/#onStart() callbacks of my activities aswell as starting it at #onStop()/#onDestroy() but behaviour doesnt run as expected in any case...
I'll paste here some code snippets of what i've tried so far:
I start/stop services using:
stopService(new Intent(this,NotificationService.class));
startService(new Intent(this, NotificationService.class));
Random activity from my app (all implement this in their callbacks):
#Override
protected void onResume() {
if (Utility.isMyServiceRunning(this)){
Utility.serviceClose(this);
}
super.onResume();
}
#Override
protected void onStop() {
if (!Utility.isMyServiceRunning(this)){
startService(new Intent(this, NotificationService.class));
}
super.onStop();
}
This somehow doesnt work or brings unexpected behaviour since the app moves from many activities, and service ends up being alive when the app is running or stopped when the app is in background/finished.
I've also tried to toggle on/off service logic on service timertask every cicle by asking:
#Override
public void run() {
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService( ACTIVITY_SERVICE );
List<RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
for(int i = 0; i < procInfos.size(); i++){
if(procInfos.get(i).processName.equals("com.example.myapp")) {
return;
}
}
//service http request logic here
}
But that doesnt work either because process "com.example.myapp" never gets killed (and of course I cannot/want to force finish that), so it never issues any httprequest.
Any Ideas on how to implement this? Any help would be very welcome.
Thanks in advance.
How about binding to your service and then communicating directly with it? Implement a simple on/off boolean, expose a getter/setter on the binding, and then make sure the service checks the boolean before it does any work. That way you can disable it while the app is running without having to actually start/stop the service repeatedly.
http://developer.android.com/guide/components/bound-services.html
Solved with better handling of onStop() onResume() callbacks.