14

I need to check if my application is running in background or foreground and then perform some operations relatively to it.

I searched a lot and a clear solution is not available.

  1. Make a parent activity in its onPause() and onResume() methods keep some variable to update them accordingly. When you create any new activity inherit your parent activity. Although this is the best solution I feel to achieve my task, but sometimes if the power button is clicked even though application is in background, it's onResume() is invoked.

  2. Use GETTASKS permission - This solution is also good. But it can only used for debug purpose. Not if you want to put your app on Google Play Store.

Get Running Taks

Any other preferred solution for this?

WISHY
  • 11,067
  • 25
  • 105
  • 197

9 Answers9

12

Well this solved my issue:

  private boolean isAppOnForeground(Context context,String appPackageName) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
    if (appProcesses == null) {
        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;
        }
    }
    return false;
}
WISHY
  • 11,067
  • 25
  • 105
  • 197
10

Original Answer : https://stackoverflow.com/a/60212452/10004454 The recommended way to do it in accordance with Android documentation is

class MyApplication : Application(), LifecycleObserver {

override fun onCreate() {
    super.onCreate()
    ProcessLifecycleOwner.get().lifecycle.addObserver(this);
}

fun isActivityVisible(): String {
    return ProcessLifecycleOwner.get().lifecycle.currentState.name
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppBackgrounded() {
    //App in background

    Log.e(TAG, "************* backgrounded")
    Log.e(TAG, "************* ${isActivityVisible()}")
}

@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onAppForegrounded() {

    Log.e(TAG, "************* foregrounded")
    Log.e(TAG, "************* ${isActivityVisible()}")
    // App in foreground
}}

In your gradle (app) add : implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

Then to check the state at runtime call MyApplication().isActivityVisible()

Yonko Kilasi
  • 337
  • 3
  • 9
6

You can check this using process lifecycle owner.

fun isAppOnForeground(): Boolean {
return ProcessLifecycleOwner.get().getLifecycle().getCurrentState()
    .isAtLeast(Lifecycle.State.STARTED);
}
Tushar Pingale
  • 337
  • 2
  • 7
  • 18
  • Thank you for this, this is a proper solution vs using **ActivityManager.getMyMemoryState(appProcessInfo)** as I have seen it not working on some devices properly. – Nishant Pardamwar Jan 13 '22 at 05:39
4

use AppVisibilityDetector, I implement this class to detect the app visibility status. it can detect the foreground and background status and perform the callback method.

 AppVisibilityDetector.init(MyApp.this, new AppVisibilityCallback() {
    @Override
    public void onAppGotoForeground() {
        //app is from background to foreground
    }
    @Override
    public void onAppGotoBackground() {
        //app is from foreground to background
    }
});

the MyApp is your Application class

public class MyApp extends Application { ... }

you don't need add some other codes to your Activity or any permissions in the AndroidManifest.xml

zyc zyc
  • 3,805
  • 1
  • 14
  • 14
2

You can use ActivityManager.RunningAppProcessInfo class to check the app status.

public boolean isForegrounded() {
    ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
    ActivityManager.getMyMemoryState(appProcessInfo);
    return (appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND ||
            appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE);
}
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
1

You can use this code to get the status of foreground(true) running of your app

public boolean isAppForground(Context mContext) {
    ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    if (!tasks.isEmpty()) {
        ComponentName topActivity = tasks.get(0).topActivity;
        if (!topActivity.getPackageName().equals(mContext.getPackageName())) {
            return false;
        }
    }
    return true;
}
  • This requires the GET_TASKS permission, which is not a valid answer according to point #2 in the question. – JM Lord Jun 09 '17 at 19:17
0

Use the following Function to check if your application is in Background or Foreground

    public static Boolean getProcessState(Context mContext) {
    ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);

    boolean noProcessOnForeground = true;
    boolean isProcessForeground = false;

    System.out.println("Checking if process: " + mContext.getApplicationInfo().processName + " is Foreground or Background");
    List<ActivityManager.RunningAppProcessInfo> current_processes = am.getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo appProcess : current_processes) {
        if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {

            noProcessOnForeground = false;
            if ((mContext.getApplicationInfo().processName).equalsIgnoreCase(appProcess.processName)) {

                isProcessForeground = true;
                System.out.println("Process is Foreground");
                break;
                //   Toast.makeText(getApplicationContext(), "Process is Foreground", Toast.LENGTH_SHORT).show();
            } else {


                System.out.println("Process is Background");
                //    Toast.makeText(getApplicationContext(), "Process is Background", Toast.LENGTH_SHORT).show();
                isProcessForeground = false;
                break;
            }
        }
    }

    if (noProcessOnForeground) {

        System.out.println("there is no process on foreground so setting " + mContext.getApplicationInfo().processName + " as background");
        isProcessForeground = false;
    }

    return isProcessForeground;
}
Suyog Gunjal
  • 287
  • 4
  • 7
0

Just want to use below code in Activity/Fragment:

final boolean isAlive = AppVisibilityHelper.isForeground(HomeActivity.this);

Want to make one class like below:

 public class AppVisibilityHelper{

        public static boolean isForeground(final Context context) {
            final String packageName = "com.acb.android";
            ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1);
            ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
            return componentInfo.getPackageName().equals(packageName);
        }
    }

If you want to check it after every one second then use below code in Activity:

 Runnable CheckAppIsRunning = new Runnable() {
        @Override
        public void run() {
           final boolean isAlive = AppVisibilityHelper.isForeground(HomeActivity.this);
                if (isAlive) {
                    // App is running
                } else {
                    // App is not running
                }
            }
            appIsRuningHandler.postDelayed(CheckAppIsRunning, 1000);
        }
    };

And in onCreate() just call it once like:

appIsRuningHandler.postDelayed(CheckAppIsRunning, 1000);
SWAPDROiD
  • 357
  • 3
  • 15
0

check app is in forground state or background state

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
   List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();

   final String packageName = getPackageName();
    for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses)
   {

   if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND && appProcess.processName.equals(packageName))
      {

       //if app in background state this will execute

        Intent intent = getPackageManager().getLaunchIntentForPackage("hinditextonphoto.com.allcomponents");
        startActivity(intent);
        System.out.println("bbbbbbbbbbbbb    background");
      }

       else if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName))
       {

       //if app in forground state this will execute
         System.out.println("bbbbbbbbbbbbb    forground");

       }

  }
dileep krishnan
  • 326
  • 4
  • 7
  • guys use this code to check app is in forground state or background state u will exact one! keep rock!.......... – dileep krishnan Nov 18 '17 at 07:48
  • NOTE: When using a `BroadcastReceiver` or `Service` the value of `appProcess.importance` when the app is in the background is `300` or `IMPORTANCE_SERVICE`. – Joshua Pinter Feb 25 '20 at 22:04