如何从服务中检查一个活动是否在后台/前台运行?

6
我创建了一个服务,从活动的onCreate方法开始,并在活动的onDestroy方法中停止。现在我需要从服务的某个方法中检查活动是否在前台/后台运行(例如应用程序被强制关闭的情况)。我该怎么做?
  1. 我需要这样做,因为据我所知,如果应用程序被强制关闭或发生任何崩溃,就没有保证会调用活动的onDestroy方法。因此,我的服务在活动启动时启动,但在任何崩溃或强制关闭事件后不会停止。
  2. 我看到了this link可以检查前台活动。但是我需要检查正在运行的活动的状态(无论是前台还是后台)
4个回答

12

最终更新

查看所有活动:

@Override
protected void onStop() {
super.onStop();

    if (AppConstants.isAppSentToBackground(getApplicationContext())) {
        // Do what ever you want after app close simply Close session

    }
}

检查我们的应用程序是否正在运行的方法:

public static boolean isAppSentToBackground(final Context context) {

    try {
        ActivityManager am = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        // The first in the list of RunningTasks is always the foreground
        // task.
        RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
        String foregroundTaskPackageName = foregroundTaskInfo.topActivity
                .getPackageName();// get the top fore ground activity
        PackageManager pm = context.getPackageManager();
        PackageInfo foregroundAppPackageInfo = pm.getPackageInfo(
                foregroundTaskPackageName, 0);

        String foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo
                .loadLabel(pm).toString();

        // Log.e("", foregroundTaskAppName +"----------"+
        // foregroundTaskPackageName);
        if (!foregroundTaskAppName.equals("Your App name")) {
            return true;
        }
    } catch (Exception e) {
        Log.e("isAppSentToBackground", "" + e);
    }
    return false;
}

回答再次更新

使用以下方法并填入你的包名。如果你的任何活动在前台运行,它将返回true。

public boolean isForeground(String myPackage){
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
 List< ActivityManager.RunningTaskInfo > runningTaskInfo = am.getRunningTasks(1); 

     ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
   if(componentInfo.getPackageName().equals(myPackage)) return true;
return false;
}

更新回答

首先检查此链接:检查 Android 应用是否在后台运行

http://developer.android.com/guide/topics/fundamentals.html#lcycles 是 Android 应用生命周期的描述。

当活动进入后台时,onPause() 方法将被调用。所以你可以在这个方法中停用更新通知。

public static boolean isApplicationSentToBackground(final Context context) {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    if (!tasks.isEmpty()) {
      ComponentName topActivity = tasks.get(0).topActivity;
      if (!topActivity.getPackageName().equals(context.getPackageName())) {
        return true;
      }
    }

    return false;
  }

同时在清单中添加权限。

<uses-permission android:name="android.permission.GET_TASKS" />

1
谢谢您的回答,但我不想使用任何活动方法,因为我想从服务中检查特定的活动/应用程序是否正在运行... - CrazyLearner
1
谢谢,您最后的编辑部分地完成了我的任务,现在我该如何从正在运行的服务中检查我的应用程序的所有活动是否在后台运行呢? - CrazyLearner
@Override protected void onStop() { super.onStop();if (AppConstants.isAppSentToBackground(getApplicationContext())) { // 在应用程序关闭后,执行任何您想要的操作,简单地关闭会话 }} - Hassaan Rabbani
要获取isApplicationInBackground值,您需要列出正在运行的前台应用程序,并检查我的应用程序是否在其中。但是,有两种情况下应用程序不会出现在前台列表中:1. 如果我的应用程序真的在后台运行,或者2. 我的应用程序崩溃了并且不在后台模式下。因此,通过这些try catch块代码,我如何确保我的应用程序没有崩溃? - CrazyLearner
让我们在聊天中继续这个讨论。点击此处进入聊天室 - Hassaan Rabbani
显示剩余5条评论

7

很不幸,自Android API 21 (Android Lollipop)开始,getRunningTasks()已被弃用:

此方法在API级别21中被弃用。从LOLLIPOP开始,第三方应用程序无法再使用此方法:引入文档为中心的最近文件意味着它可能会向调用者泄漏个人信息。为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务以及可能与不敏感的任务(例如Home)相关的一些其他任务。


2
请纠正我,但问题是关于在同一应用程序中从服务检查活动,所以“至少调用者自己的任务”是否涵盖了这一点? - Abandoned Cart

0

尝试使用以下方法检查您的应用程序是否在后台运行:

public boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }

        return isInBackground;
    }

-3
检查this链接,特别是检查展示这部分代码的答案。
public class MyApplication extends Application {

 public static boolean isActivityVisible() {
return activityVisible;
}  

public static void activityResumed() {
 activityVisible = true;
}

public static void activityPaused() {
activityVisible = false;
 }

private static boolean activityVisible;
}

希望这能帮到你。


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