如何知道我的应用程序在Android中是在前台还是后台?

14

我需要检查我的应用程序是在后台运行还是前台运行,然后相对地执行一些操作。

我搜索了很多,没有明确的解决方案。

  1. 创建一个父活动,在其onPause()和onResume()方法中保留一些变量以相应地更新它们。当您创建任何新活动时继承您的父活动。虽然这是我感觉实现我的任务的最佳解决方案,但有时即使应用程序在后台,如果点击了电源按钮,也会调用它的onResume()方法。

  2. 使用GETTASKS权限-此解决方案也很好。但它只能用于调试目的。如果您想将应用程序放在Google Play商店上,则无法使用。

获取正在运行的任务

还有其他更优选的解决方案吗?

9个回答

12

好的,这解决了我的问题:

  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;
}

10

原始答案:https://dev59.com/66Dia4cB1Zd3GeqPKdtf#60212452 根据Android文档推荐的方法是

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
}}

在你的gradle(app)中添加:implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

然后在运行时检查状态,调用MyApplication().isActivityVisible()


太棒了,解决方案简洁明了,谢谢。 - nweke_onyekachukwu

6
您可以使用进程生命周期所有者来检查这一点。
fun isAppOnForeground(): Boolean {
return ProcessLifecycleOwner.get().getLifecycle().getCurrentState()
    .isAtLeast(Lifecycle.State.STARTED);
}

谢谢您提供的解决方案,这是一个正确的解决方案,相对于使用 **ActivityManager.getMyMemoryState(appProcessInfo)**,我已经看到它在某些设备上无法正常工作。 - Nishant Pardamwar

4

使用AppVisibilityDetector,我实现了这个类来检测应用程序的可见性状态。它可以检测前台和后台状态并执行回调方法。

 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
    }
});

MyApp是你的Application类

public class MyApp extends Application { ... }

您不需要在Activity中添加其他代码或在AndroidManifest.xml中添加任何权限


2
你可以使用ActivityManager.RunningAppProcessInfo类来检查应用程序的状态。
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);
}

1
你可以使用此代码获取应用程序前台运行的状态(true)。
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;
}

这需要 GET_TASKS 权限,但根据问题中的第二点,这不是一个有效的答案。 - JM Lord

0

我只想在Activity/Fragment中使用以下代码:

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

想要创建一个如下的类:
 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);
        }
    }

如果您想每隔一秒钟检查一次,请在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);
        }
    };

而在onCreate()中只需调用它一次:

appIsRuningHandler.postDelayed(CheckAppIsRunning, 1000);

0

检查应用程序是否处于前台状态或后台状态

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
注意:当使用BroadcastReceiverService时,应用程序在后台运行时的appProcess.importance值为300IMPORTANCE_SERVICE - Joshua Pinter

0
使用以下函数来检查您的应用程序是在后台还是前台:
    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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接