Hi i am using service on devises from API 15.
I need to catch when service die itself or when user kill app from task and service stop.
here is my service:
#Override
public void onCreate() {
super.onCreate();
mTimerIntent = new Intent(SERVICE_TIMER_BROADCAST);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null){
mTimerType = intent.getExtras().getInt(TIMER_TYPE_KEY);
mTimer.run();
}
return START_NOT_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("test", "onDestroy");
setLoginStatusFailed();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.d("test", "onTaskRemoved");
setLoginStatusFailed();
}
private void setLoginStatusFailed(){
new USB_LogOut(getApplicationContext());
}
on KitKat device it works great, but when I tried it on 4.0 it is does't work...
Any ideas why it happen and how to fix this?
Services can't run 24 hours a day. At some point the system will very likely need to kill your process to have memory for elsewhere, and you will go away without a call to onDestroy(). Later the system will restart the process and service.
You can return start_sticky in onStartCommand for restart the service if the service killed by the system or user as well .
http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle
You can refer Google forum for more details https://groups.google.com/forum/#!topic/android-developers/2DTkEk73xpk
Related
I have created a service and called this service class from BaseActivity.
Intent serviceIntent = new Intent(this, UserAvailabilityService.class);
startService(serviceIntent);
public class UserAvailabilityService extends Service {
private static final String TAG = UserAvailabilityService.class.getSimpleName();
boolean isChecked = false;
boolean isUserAvailable = false;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
isChecked = getAvailableStatusFromFref();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand()");
return START_NOT_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(TAG, "onTaskRemoved()");
if(isChecked) {
//Hit a api
}
else
{
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
#Override
public void onLowMemory() {
super.onLowMemory();
Log.i(TAG, "onLowMemory()");
}
}
If app crashes or closed from task manager then that time i want to hit api.
Right Now, When i am swipping the app from background this onTaskRemoved method is calling. and i am hitting the api.
But when i am closing the same app from task manager (Setting->Apps->App name->Force Stop) then this onTaskRemoved method is not calling.
Any idea,please let me know.
Not possible. You cannot tell from within an app whether the app will be terminated. You could watch for termination from a second app, but at any time the first can be closed without notice. Not to mention the variety of ways that both apps could be shut down (for example, they could just pull the battery). You should never write code that requires you to do something on shutdown, because it will never be reliable.
The best you can do is calling isFinishing() which checks if it is being destroyed from you onPause() method
#Override
protected void onPause(){
super.onPause();
if(isFinishing){
callApi();
}
}
So I have code that I want called when my application is closed. Not just when it is sent to the background or the surface is destroyed. How do I do this? Is there a method that I can override in a SurfaceView or Activity class?
New Edit - current BackgroundService class:
public class BackgroundService extends Service {
private String savedString;
public void onCreate() {
System.out.println("Service created");
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("start command: ");
savedString = intent.getStringExtra("myString);
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
return null;
}
public void onTaskRemoved(Intent rootIntent) {
System.out.println("the saved string was: " + savedString);
super.onTaskRemoved(rootIntent);
}
public void onDestroy() {
System.out.println("destroyed service");
super.onDestroy();
}
}
Where I then have this in my other class:
Intent serviceIntent = new Intent(activity.getApplicationContext(), BackgroundService.class);
serviceIntent.putExtra("myString", "this is my saved string");
activity.startService(serviceIntent);
you need to add a background service
public class BackgroundServices extends Service
{
#Override
public void onCreate() {
Toast.makeText(this, "start", Toast.LENGTH_SHORT).show();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
then in your activity. where you want to trigger this service
use
startService(new Intent(getBaseContext(), BackgroundServices.class));
in your case it will be call on onDestory function of that activity
Yes when the process is terminated
That is not possible in general. Nothing in your app is called when the process is terminated.
For example when you open the running apps screen, and swipe away the app to stop it from running
That is a task removal. It may result in your process being terminated, and there are many ways in which your process can be terminated that has nothing to do with task removal.
To detect task removal, override onTaskRemoved() in a Service.
I have an alarm broadcast receiver where I want to check if my app is completely closed, which means app is neither running in foreground nor background.
Can anyone tells me how can I check this ?
You can create a service and overwrite the onTaskRemoved() method
From the Documentation
the user has removed a task means swiping the app out from the task
list. Stopping the Service from the phone's settings does not trigger
Service.onTaskRemoved().
Code:
public class AppStopped extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service", "Service Started");
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("Service", "END");
Toast.makeText(getApplicationContext(), "App Stopped", Toast.LENGTH_SHORT).show();
//Code here
stopSelf();
}
}
In Manifest:
<service android:name="com.example.AppStopped"
android:stopWithTask="false" />
Start the service in your activity like:
startService(new Intent(getBaseContext(), AppStopped.class));
In your Application class:
public class MyApplication extends Application {
#Override
public void onTerminate() {
super.onTerminate();
// your app is closed
}
}
I am trying to create SyncAdapter running background operation (without foreground notification).
It is working, except the case when activity (task) which triggered ContentResolver.requestSync(...) is swiped away from recent applications. In that case process is killed and onPerformSync(...) is not finished.
I know, this is expected Android behavior, but in regular Service I would set
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_REDELIVER_INTENT;
}
or maybe use
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
restartSynchronization();
}
to retry synchronization, but this is not working in the SyncAdapterService.
How can I ensure synchronization continues/retry after activity is swiped away from recent applications?
Thank you in advance.
After some reseach I found out, that onTaskRemoved(...) is called only when startService(...) is called and not when someone only binds to it.
So I did work around by starting service in onBind(...) and stopping it and its process in onUnbind(...) methods.
This is final code:
public class SyncAdapterService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static MySyncAdapter sSyncAdapter = null;
#Override
public void onCreate() {
super.onCreate();
synchronized (sSyncAdapterLock) {
if (sSyncAdapter == null) {
sSyncAdapter = new MySyncAdapter(getApplicationContext());
}
}
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
/*
* Rescheduling sync due to running one is killed on removing from recent applications.
*/
SyncHelper.requestSyncNow(this);
}
#Override
public IBinder onBind(Intent intent) {
/*
* Start service to watch {#link #onTaskRemoved(Intent)}
*/
startService(new Intent(this, SyncAdapterService.class));
return sSyncAdapter.getSyncAdapterBinder();
}
#Override
public boolean onUnbind(Intent intent) {
/*
* No more need watch task removes.
*/
stopSelf();
/*
* Stops current process, it's not necessarily required. Assumes sync process is different
* application one. (<service android:process=":sync" /> for example).
*/
Process.killProcess(Process.myPid());
return super.onUnbind(intent);
}
}
I have a Service in my android application which stop only when quitting the application.
public class MyService extends Service {
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
if(intent != null){
//......
}
} catch (Throwable e) {
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onCreate() {
super.onCreate();
//......
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This service calls its onCreate() method sometimes itself while running.When checking the state of service it is running but its functionalities does not work.I am stuck on this for many hours.What is the problem here?I tried onLowMemory() in this service.But not result.
If you return START_STICKY in the onStartCommand(), the Service gets created again if its killed by system (probably on a low memory condition). The same thing must have happened in your case and onCreate() got called.