I have an android application i need one function or any broadcast receiver that can check if the app is closed.. i don\'t need to call on destroy in every activity (there i
Basically looking at your problem, you want to track the state changes in an app.
It can be quite difficult to get it right taking care of all the use cases. But there is an amazing library which works very well and is super-easy to use - RxAppState.
I have been using this library for quite a long time now and it works very well in all cases. I highly recommend you to try this.
This answer uses ProcessLifecycleOwner to detect application visibility.
which is a part of Android Architecture Component .
implementation "android.arch.lifecycle:extensions:1.1.1"
public class AppController extends Application implements LifecycleObserver {
///////////////////////////////////////////////
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onEnterForeground() {
Log.d("AppController", "Foreground");
isAppInBackground(false);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onEnterBackground() {
Log.d("AppController", "Background");
isAppInBackground(true);
}
///////////////////////////////////////////////
// Adding some callbacks for test and log
public interface ValueChangeListener {
void onChanged(Boolean value);
}
private ValueChangeListener visibilityChangeListener;
public void setOnVisibilityChangeListener(ValueChangeListener listener) {
this.visibilityChangeListener = listener;
}
private void isAppInBackground(Boolean isBackground) {
if (null != visibilityChangeListener) {
visibilityChangeListener.onChanged(isBackground);
}
}
private static AppController mInstance;
public static AppController getInstance() {
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
// addObserver
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
}
And use it like this:
AppController.getInstance().setOnVisibilityChangeListener(new ValueChangeListener() {
@Override
public void onChanged(Boolean value) {
Log.d("isAppInBackground", String.valueOf(value));
}
});
Don't forget to add application name
into your manifest
<application
android:name="myPackageName.AppController"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"">
Done.
(Kotlin example)
https://github.com/jshvarts/AppLifecycleDemo
You can use this function to determine if the app is closed ( not in background nor in the foreground).
private boolean isAppRunning() {
ActivityManager m = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> runningTaskInfoList = m.getRunningTasks(10);
Iterator<ActivityManager.RunningTaskInfo> itr = runningTaskInfoList.iterator();
int n=0;
while(itr.hasNext()){
n++;
itr.next();
}
if(n==1){ // App is killed
return false;
}
return true; // App is in background or foreground
}
You can also check if the app is in foreground by using this function: https://stackoverflow.com/a/8490088/9005188
Like @S.R answer, you can also use the interface "Application.ActivityLifecycleCallbacks" in ur custom application, and then in the "onActivityStopped" use the "isAppOnForeground(Context)" method.
public class MyApplication extends Application import Application.ActivityLifecycleCallbacks{
[ Code of ur app class...]
/* START Override ActivityLifecycleCallbacks Methods */
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
mActivitiesBackStack.add(activity.getClass());
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
if(!AppUtils.isAppOnForeground(this)){
[Code when app in background...]
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
if(mActivitiesBackStack.contains(activity.getClass())){
mActivitiesBackStack.remove(activity.getClass());
}
}
/* END Override ActivityLifecycleCallbacks Methods */
[ Code of ur app class...]
This is called every time the app goes in background and not when it get closed. If you put the "isAppOnForeground" inside the "onActivityDestroyed" it won't work with the code above for "isAppOnForeground" because it can't find the process (I think), maybe changing the code above or with another implementation it will work. The "onActivityDestroyed" will get called when the app is closed, so if you can check if the app is in background when it is called (so the app is already closed) you can grep exactly the moment when the app is being closed.
Code of "isAppOnForeground" (I'm using it in a Utils static class):
public static boolean isAppOnForeground(Context context) {
boolean ret = false;
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if(appProcesses != null){
String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
ret = true;
}
}
}
return ret;
}
Hope this is helpful, see you bye and happy coding ! :D
use one service which is start from Application class.
public class AppService extends Service {
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
//here you will get call when app close.
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
start this service from Application class.
@Override
public void onCreate() {
super.onCreate();
Intent intent = new Intent(getApplicationContext(), AppService.class);
startService(intent);
}
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isAppForground(context)) {
// App is in Foreground
} else {
// App is in Background
}
}
private boolean isAppOnForeground(Context context,String appPackageName) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
//App is closed
return false;
}
final String packageName = appPackageName;
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
// Log.e("app",appPackageName);
return true;
}else{
//App is closed
}
}
return false;
}
}
Add this permission too
<uses-permission android:name="android.permission.GET_TASKS" />
try this hope it helps