Stop services when exit Application (swiping Application away in Android's task) - android

I have a service based on a check box in Activity(user can start or stop it).
Once it start, it will run in background, and should not be stopped when the activity is onDestroy().
However, I want to stop it when user swipes the Application away in Android's task, because this service need to restart when user reopen the App.
How can I do that? Is it possible to stop service in onTerminate() method in Application.

How can I do that?
You can do it adding this on your manifest.xml on your service
android:stopWithTask="true"
If you want to controle it you can also do it on your Service adding the onTaskRemoved()
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
//STOP SERVICE OR WHATEVER YOU WANT
}
If you use onTaskRemoved() don't add android:stopWithTask="true" because it won't be called*

You can set a flag to false when onPause() or onDestroy() is called.Save this in SharedPreferences.Use this flag to check whether your app is running or not. Start your service only if flag is true.

Related

stopService() doesn't call onDestroy [duplicate]

I have big problems with stopping a service, which plays audio file. I want to stop the current service before I play another file.
Activity:
public void playTrack(View view){
Intent i=new Intent(this,playService.class);
i.setAction("com.c0dehunterstudios.relaxer.PLAY");
if(isPlaying){
stopService(i);
isPlaying=false;
Log.v("ACTIVITY", "Stopping..");
}
startService(i);
isPlaying=true;
}
Service:
#Override
public void OnDestroy(){
Log.v("SERVICE","Service killed");
player.stop();
super.onDestroy();
}
But sadly it doesn't work - actually it doesn't even come down to the "Service killed" inside OnDestroy().
What am I doing wrong?
First, it's onDestroy, not OnDestroy . Second, you must use the #Override annotation for compile-time checking, so your Service code should look somewhat like this:
#Override
public void onDestroy(){
Log.v("SERVICE","Service killed");
player.stop();
super.onDestroy();
}
First, you need to clarify how many types of services in Android. AFAIK, there are:
Foreground service.
Background service.
Bound service.
Intent service.
These services stop in different ways.
Foreground: only stop when you intentionally stop it by calling stopService() in activity or fragment where you start that service or call stopSelf() in its own service. And Please note only these methods trigger service's onDestroy().
Background: stopService() and stopSelf() do in the same way as foreground. Moreover, you should know this service is in the same thread with activity or fragment calling it, so if you destroy activity or fragment, this service will stop also, but without calling onDestroy(). It basically destroys underground. Thus, if you want to catch when this service stops you need to add android:stopWithTask="false" when declaring service in Manifest file like this:
<application>
//....
<service android:name=".services.catchingStopService"
android:stopWithTask="false" />
//....
</application>
And now in your service class, you can override this method which triggers whenever this service stops:
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
// Your job when the service stops.
}
Bound: you need to handle by your self by bindService() and unbindService(), you will find out it's totally the same as starService() and stopService()
Intent: this type of service stops by itself when it finishes its jobs. And you can use ResultReceiver to communicate between service and activity or fragment. It's similar to BroadcastReceiver. You can search for example on Google easily.
Summary: base on your purpose, pick the type of service satisfying you. And they all agree with:
Don't count on onDestroy() to know when service stops because it
sometimes gets called underground; more accurately, onDestroy calls
when stopService() or stopSelf() calls (BoundService works in the
same way, I think, but by a similar method, maybe unBind(), I did not
test yet).
Use attribute android:stopWithTask="false", instead to know when the
service really stops.
All types of service stop when the device shutdown or OS kills it if
device leaks of memory.
You also should have a look at flag return by onStartCommand() to
be able to deal with when services stop like restart service again or
something. Here are some keyword you can search:
START_STICKY
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
<actionandroid:name="android.intent.action.QUICKBOOT_POWEROFF" />
I had a similar problem even with onDestroy correctly set up - the answer for which could be useful for people coming to this page. For me, onDestroy was not called immediately during stopService, sometimes for a very long time - leaving the service doing work when it should have stopped.
The answer is that this is expected behaviour - I can guess but don't exactly know why. So my solution in this case was to create a public static method to stop the actions of the service manually, which happens at the time it's called, then stopService() will call onDestroy in it's own good time...
In the case for this example (which is probably long gone, I would probably decide to keep the service running until it's expected to quite the app, but provide ways to change audio file, while the service is still active.
In my case I was printing a log inside the onDestroy and It was not printing the log and I thought onDestroy not calling when I call stopService. but in Android studio many times does not print the log so you can once double check or verify with the debug or toast.

Stop the Service on Destroy of Application

I am confused right now , about service concept of running and stopping:
what i want to do:
Start Location service at the very start of application.
Keep getting location updates and store them to shared preference
Stop the service in onDestroy of Application scope!
So far i have searched and studied we can only do following things with service(correct me if i'm wrong):
Stop the service automatically by binding it to related activities/fragments/views , when all of them destroyed service unbind itself automatically so we can call stopself method in unbind
return START_NOT_STICKY in onStartCommand to tell OS , don't recreate it , and create intent local service , after completion of some work it will destroy itself.
Stopping the service manually , by declaring it's intent in some kind of static scope and stopping the service in on onActivityDestroyed of Application class [I am not sure what will happen? , maybe service will destroy each time any activity will be destroyed ? or it will be destroyed only when overall application get's destroyed?]
Either way , i am bit confused and beat , been trying to adjust my Location service with given details for 2 days
If you start your Service using START_NOT_STICKY, then your app will kill your service once your entire application is closed from background i.e. you cleaned your app from home screen.
Here START_NOT_STICKY states that you need not recreate service in case it is been killed.
If this is not the case then you have to manually kill it by your self.
Like
Intent lintent = new Intent(context, LocationService.class);
context.stopService(lintent);
You can use this code at point where your application kills.
That's it. You are good to go with this.
First of all, launch the "LocationService" on your app start:
public class MyApp extends Application {
private static final String TAG = "MyApp";
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "App started up");
startService(new Intent(this, MyLocationService.class));
}
}
Second :
As you said, the Service should better run with the "START_NOT_STICKY" flag
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
Thrid:
Once the system kills your app, the Service will automatically be killed, so no problems at all.
There is no onDestroy() method on the Application object, the only similar event is onTerminated() and it is not being launched on production devices.
onTerminate
Added in API level 1 void onTerminate () This method is for use in
emulated process environments. It will never be called on a production
Android device, where processes are removed by simply killing them; no
user code (including this callback) is executed when doing so.
More information:
https://developer.android.com/reference/android/app/Application.html#onTerminate()
Btw, If you want the MyLocationService to send updates of the location to your app (when it is open), you should consider to use Otto or EventBus (I recommend you this last one because of the simplicity to use it). You can even configure the #Suscriber to receive updates of old retrieved locations if you want.
I will try to explain in a easiest way :)
There are two type of service
IntentService and Service
IntentService when started will kill itself once it treated the content of it onHandleIntent method
as for Service well this one will not end until you give it the command to do so even if your start it using the context of an activity. It will also stop when the application is stopped in an extreme case (by system (Settings/application/YourApp/stop app OR an app crash)
Easiest way is First of all start IntentService with AlarmManager at some repeating time (10 mintutes), then in onHandleIntent() get Location and store into preference.
No Need bind to your activity, the IntentService automatically stops itself after saved in preferences.
Yes you can stop the service in onDestroy() of the activity:
#Override
public void onDestroy(){
Log.v("SERVICE","Service killed");
service.stop();
super.onDestroy();
}

How to kill a foreground service along with the application

I am running a foreground service which is doing some work in the background while the user is interacting with my application.The problem which occurs is that when the user comes out of the application and kills the application from the home screen the service is not destroyed.Is there any way to kill the service when my application dies.
With "kills the application from the home screen" I'm assuming you mean swiping away the app from the task manager? In that case, there is a convenient callback in the Service class that lets you handle this.
Simply override that method and call stopSelf().
You can do following to stop the service
call stopService method in onDestroy method of activity
hope this will solve your problem
why do you make the service foreground?
If it's only doing work while the user interacts with your application,
maybe you should not keep it foreground.
Just call stopService() for your service in onDestroy() method of your main Activity.
I solved it by calling stopService(intent); in my MainActivity where I call the service from another Class.
#Override
protected void onDestroy()
{
super.onDestroy();
stopService(intent);
}
But as For the yourservice.class needed to have the onDestroy method, it is crucial.
#Override
public void onDestroy()
{
super.onDestroy();
stopForeground(true);
stopSelf();
}

Call onDestroy() of Service

I want to call
onDestroy()
method of Service in android.
I already searched a lot on internet and many answers are like if
service force stop or somehow its onDestroy() will never call.
But I really need to know when service is stop.
My project is about music player.
So it uses service and there is an ongoing notification.
I need to find out when the service stop? and need to stop the music and remove the notification.
But it never shows any log of onDestroy().
Can anyone help me what is the alternative for it? if not onDestroy() then which method and how?
Edit:
I don't want to call onDestroy() explicitly. I want to remove notification when I remove my app from the device menu of running applications. Because when I stop my application, onDestroy() don't call and my notification remains in the status bar.
I have started my service with this code.
Intent playin = new Intent(this, MusicService.class);
startService(playin);
From within the Service class, call:
stopSelf();
From within another class, like your MainActivity for example:
Intent i = new Intent(this, ServiceName.class);
stopService(i);
Both of these will stop your service. Make sure you are returning START_NOT_STICKY so that the service doesn't start back up again.
When you want to stop your service then simply fire an intent to stop the service as shown below.
Intent intent = new Intent();
intent.setClass(getApplicationContext(), YourService.class);
stopService(intent);
This is to stop service forcefully.When you stop service in this manner it's guaranteed that onDestroy method is called by android framework.
Hope this helps to solve you issue.
I want to call onDestroy() method of Service in android.
Do not call this method directly
public void onDestroy ()
Called by the system to notify a Service that it is no longer used and
is being removed. The service should clean up any resources it holds
(threads, registered receivers, etc) at this point. Upon return, there
will be no more calls in to this Service object and it is effectively
dead. Do not call this method directly.
However you can check if the service is running or not.
I need to find out when service stop? and need to stop music and
remove notification.
Use the following way -
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
Then call it using - isMyServiceRunning(MyService.class).
Reference:
1) Service onDestroy().
2) how-to-check-if-a-service-is-running-in-android.
You should use Foreground service. In your case, I think it would be the best choice.
Foreground services show a status bar notification, so that users are actively aware that your app is performing a task in the foreground and is consuming system resources. The notification cannot be dismissed unless the service is either stopped or removed from the foreground.
To work with foreground service you first need to declare permission <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> in your manifest. It is a normal permission so doesn't requires user action.
then, you can start the service for you Activity or other component using applicationContext.startForgroundService(intent). this is to tell the system that this will be a foreground service.
You need to start the foreground service from within your service(usually in onStartCommand()) using startForeground(int, Notification) and stop the service foreground service using stopForeground(boolean)(it takes a boolean asking whether you want to remove the notification or not)
after starting foreground service, if you close your app or the service stops itself, the notification will be remove too.
Note: when you manually want to stop the service, you should call stopSelf() or stopService() as calling stopForeground() is not enough, it merely remove the notification from the status bar.

RemoteService - restarts after closing the launching Activity

I'm blocked with this for a few days and can't find the answer on this.
I start a remote service from an Activity. After starting the service, I close the launching Activity.
I close the main Activity from the task manager like this: home_btn long press and the list of opened app appears and then swipe left on the main Activity.
The thing that happens is that my service gets restarted! even thought it is a remote service, that has it's own process, doesn't depend on the launching activity!
All the internal variables are going to be reset and I don't want that.
-I don't want to use useForeground() method because I don't want my service to be visible in Notification
I currently start a Remote Service like this and the service starts(I can see it in the menu Settings->Apps-> tab Running):
btnStartSrv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startService(new Intent("com.example.servicerst_tst.RemoteService"));
}
});
android manifest xml looks like this:
<service android:name="com.example.servicerst_tst.RemoteService"
android:process=":serviceTST" >
<intent-filter>
<action android:name="com.example.servicerst_tst.RemoteService" >
</action>
</intent-filter>
</service>
the service class:
public class RemoteService extends Service{
#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;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
I'm seeing the service restarting or reseting .. in the DDMS.
When closing main Activity the service disappears from the list in the DDMS and the gets started by itself in about 2 seconds. This can be visible in the service also. If you place some internal variables that get change during the life of the service. They will get reset, like the the service is restarting itself after closing the main Activity.
I just want my service not to reset, restart when I'm closing the main launcher Activity.
If the user closes the launcher Activity, from task manager or by his mistake, I want the service to run in background.
Am I doing something wrong here or missing something from my code to prevent restarting?
Why is reseting the service?
From Android Developers - Services : "if the service is declared to run in the foreground (discussed later), then it will almost never be killed. Otherwise, if the service was started and is long-running, then the system will lower its position in the list of background tasks over time and the service will become highly susceptible to killing—if your service is started, then you must design it to gracefully handle restarts by the system".
Declaring your service to run in the foreground has specific requirements: "A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground." and "To request that your service run in the foreground, call startForeground()." I know you said you don't want it to be a foreground service, but you have to live with the parameters Android sets out for you.
Solved problem with restarting service when launching Activity closes!
You should use startForeground() to not have this issue.
So startForeground() solved the restarting problem when closing launching Activity.
I've made also the service, restarting reliable.
Still I have a question..how the services ... like facebook and other big services run in background without any startForeground() implemented.
Also they are not killed by the system and they run in background forever without any startForeground() implementation. they live forever in background. For sure is somehow possible.
Does anyone know how?
How to avoid notification but still implementing the startForeground() method:
This is done By implementing the notification without
.setSmallIcon(R.drawable.ic_launcher)
for other details see
How to correctly handle startForegrounds two notifications

Categories

Resources