如何检测android应用程序是否在前台(API 21)

如何检测android应用程序是否在前台(API 21),android,google-cloud-messaging,android-5.0-lollipop,Android,Google Cloud Messaging,Android 5.0 Lollipop,当收到GCM消息时,我的应用程序的行为取决于它是否在前台。在API 21之前,我使用了以下内容: Boolean onForeground = this.getPackageName().equalsIgnoreCase( ((ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE)) .getRunningTasks(1).get(0).topActivity.getPack

当收到GCM消息时,我的应用程序的行为取决于它是否在前台。在API 21之前,我使用了以下内容:

Boolean onForeground = this.getPackageName().equalsIgnoreCase(
            ((ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE))
            .getRunningTasks(1).get(0).topActivity.getPackageName()
);
现在getRunningTasks()已被弃用,并且在API 21上的行为有所不同,在API 21上检测我的应用是否处于前台的最佳方式是什么

谷歌推荐

public ActivityManager.RecentTaskInfo getTaskInfo ()
但我不知道如何从那里获得我需要的信息

先谢谢你


编辑:根据@commonware和@Chris Stratton的建议,我可以跟踪onResume/onPause状态。由WebView(我无法控制的内容)引起的应用程序崩溃会使系统处于错误状态。在这种错误状态下发送GCM会导致另一个崩溃,让用户感到困惑(他/她当时没有对我的应用程序做任何事情)

因此,我正在寻找另一种解决办法。 (我使用的是片段,只有一个活动,所以实现这一点很简单)

您可以使用

  • 创建一个注册在清单中的
    BroadcastReceiver
    ,它执行后台行为
  • 在活动中以正优先级动态注册
    BroadcastReceiver
    (默认值为
    0
    ),确保在
    onStart()
    /
    onResume()
    中注册,并在
    onStop()
    /
    onPause()中取消注册
    -这将执行前台行为,并应调用以确保未调用已注册的清单
    BroadcastReceiver

然后,您的GCM接收器可用于发送广播(最好使用您的另一个
BroadcastReceiver
s注册的自定义操作)动态注册的接收者(如果存在)和清单注册的接收者(如果不存在)将接收到这些信息。

我使用
getRunningAppProcesses

boolean isOnForeground = 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()))
                {
                    isOnForeground = false;
                }
            }
        }
    }
}
else
{
     List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
     ComponentName componentInfo = taskInfo.get(0).topActivity;
                if(componentInfo.getPackageName().equals(context.getPackageName()))
     {
          isOnForeground = false;
     }
}
boolean isOnForeground=true;
ActivityManager am=(ActivityManager)context.getSystemService(context.ACTIVITY_服务);
if(Build.VERSION.SDK\u INT>Build.VERSION\u code.KITKAT\u WATCH)
{
List runningprocesss=am.getrunningappprocesss();
对于(ActivityManager.RunningAppProcessInfo processInfo:RunningProcesss)
{
if(processInfo.importance==ActivityManager.RunningAppProcessInfo.importance\u前台)
{
for(字符串activeProcess:processInfo.pkgList)
{if(activeProcess.equals(context.getPackageName()))
{
isOnForeground=false;
}
}
}
}
}
其他的
{
List taskInfo=am.getRunningTasks(1);
ComponentName componentInfo=taskInfo.get(0).topActivity;
if(componentInfo.getPackageName().equals(context.getPackageName()))
{
isOnForeground=false;
}
}

使用事件总线让应用程序的UI层知道收到了GCM消息。让应用程序的UI层(活动/片段)在从前台进出时从总线注册和注销。有一种方法可以确定UI层是否没有处理事件,并进行后台处理(例如,发出
通知
)。我有三条事件总线实现此模式的示例:、Square和greenrobot。换句话说,一个活动位于onResume()和onPause()之间的前台,一个应用程序是当它的任何一个活动都是-你可以通过让他们都调用或映射到一个共同的组成部分。谢谢你的建议,这是我所考虑的,但我想避免,因为我有一个WebVIEW,有时会导致应用程序崩溃(由于内容,在我的控制之外)。这种情况将导致错误的状态。(将更新我的问题)太好了,这正是我想要的。我甚至不知道sendOrderedBroadcast(),所以我明天要读一些书。谢谢。应用程序进程可以具有前台优先级/重要性,即使不在前台。OP想知道他们的应用程序是否真的在前台,这样就不起作用了。例如,没有可见活动的流程,其服务使用了startForeground,将具有前景重要性。还有,你不是返回了你想要的相反的结果吗?