【问题标题】:How to check if an activity is running in background/foreground from a service?如何检查活动是否在服务的后台/前台运行?
【发布时间】:2014-03-18 00:18:01
【问题描述】:

我创建了一个从活动的 onCreate 开始并在活动的 onDestroy 方法上停止的服务。现在我必须从服务的方法中检查活动是否在前台/后台运行(对于某些情况,例如应用程序被强制关闭)。我该怎么做?

  1. 我需要这样做,因为据我所知,如果任何应用程序被强制关闭或任何类型的崩溃,无法保证调用活动的 onDestroy 方法。因此,在我的活动启动时启动的服务不会在任何崩溃或任何强制关闭事件后停止。

  2. 我看到this link 可以检查前台活动。但我需要检查处于任何状态(前景或背景)的正在运行的活动

【问题讨论】:

    标签: android android-activity service


    【解决方案1】:

    最终更新

    检查所有活动:

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

    答案已更新

    先查看此链接Checking if an Android application is running in the background

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

    当 Activity 进入后台时,会调用 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" />
    

    【讨论】:

    • 感谢您的回答,但我不想使用任何活动方法,因为我想从服务中检查特定活动/应用程序是否正在运行...
    • 谢谢,您上次的编辑部分完成了我的任务,现在我如何从正在运行的服务中检查我的应用程序的所有活动是否都在后台......
    • @Override protected void onStop() { super.onStop(); if (AppConstants.isAppSentToBackground(getApplicationContext())) { // 在应用关闭后做任何你想做的事 关闭会话 } }
    • 要获取isApplicationInBackground 值,您已经列出了正在运行的前台应用程序,并检查我的应用程序是否在那里。但是应用程序有两种情况,不在前台列表中:1.如果我的应用程序真的在后台,或者 2.我的应用程序崩溃而不是在后台模式。那么通过那些try catch块代码,我怎么能确定我的应用程序没有崩溃???
    • 当你的应用程序崩溃时,它不在后台列表中。它被摧毁了。处于后台意味着已在应用程序上调用了 onPause
    【解决方案2】:

    很遗憾,自 Android API 21 (Android Lollipop) 起,getRunningTasks() 已被弃用:

    此方法在 API 级别 21 中已弃用。从 LOLLIPOP 开始,此方法 方法不再可用于第三方应用程序: 引入以文档为中心的最新消息意味着它可以泄露人员 给来电者的信息。为了向后兼容,它仍然会 返回其数据的一小部分:至少是调用者自己的任务, 可能还有其他一些已知的任务,例如家 敏感。

    【讨论】:

    • 如果我错了,请纠正我,但问题是关于检查同一应用程序中服务的活动,所以“至少调用者自己的任务”是否涵盖了这一点?
    【解决方案3】:

    试试这个方法来检查你的应用是否在后台:

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

    【讨论】:

      【解决方案4】:

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

      希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 2019-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多