3

检测应用程序是否在前台有很多原因。例如 - 作为 GCM/C2DM 推送通知的触发器 - 当应用程序处于前台和后台时,许多应用程序将有充分的理由实施不同的行为。其他原因可能是 - 关闭消耗宝贵资源的服务,例如在后台任务中查询服务器。

为了清楚起见:后台应用程序的定义(如我所见)是
应用程序没有任何活动被调用该onStart()方法,并且还没有调用该onStop()方法。那是因为只有在那个时候,用户才能在它的生命周期中看到活动。

从另一方面 -

  • 似乎谷歌不希望应用程序对主页按钮做出反应(它不是 API 的一部分)

  • 对“root / main”活动做出反应onBackPressed()作为离开的指标Activity肯定不是好主意(因为很多用户使用主页按钮,而不是返回按钮)

  • API中没有方法可以确定应用程序是否是前台(根据我的定义..)

如果我没有错过 API 中的某些内容,而且确实如此 -为什么没有为什么可以轻松确定应用程序是否在前台??????!!!!!!

我知道我可以做些什么来确定应用程序是否是前台在此线程中进行了描述-如何检测 Android 应用程序何时进入后台并返回前台

但正如@Emil 所说 - 它需要特殊许可,或者需要一些棘手的逻辑,这些逻辑很快就会变得难以维护,而且它闻起来像是不好的方法(尽管这就是我现在正在做的事情,因为我没有更好的主意。 ..)

我的问题基本上是

  • 是否有充分的理由没有这样的 API 方法?

  • 是否考虑应用程序是否是前台是一种不好的方法?

  • 有没有其他方法可以知道应用程序是否在前台?

4

4 回答 4

5

是否考虑应用程序是否是前台是一种不好的方法?

考虑前景与背景是合理的。

有没有其他方法可以知道应用程序是否在前台?

您可以将其大致分为两组:

  1. 希望在前台/后台状态发生变化时立即采取行动的情况

  2. 发生其他事件(AlarmManager警报、传入系统广播等)的情况,此时您希望根据您是否在前台采取不同的操作

在前一种情况下,onUserLeaveHint()是您最可靠的简单选择。我不能保证它会涵盖所有情况,但它应该处理 HOME 场景,例如。也欢迎您在静态数据成员中维护已启动活动的引用计数,并尝试使用它。

在后一种情况下,有序广播可能很有用。

于 2012-12-26T18:34:06.093 回答
1

借助新的 Android 架构组件,您可以轻松了解您的应用是在前台还是后台。

就像活动范围生命周期所有者一样,有一个通用流程生命周期所有者,您可以订阅并获取生命周期更新。

例如:

添加此代码以注册为生命周期观察者

ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleListener)

而这段代码是为了接收相关的回调

@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onApplicationOnStartEvent() {

}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onApplicationOnStopEvent() {

}

不需要时不要忘记删除观察者

ProcessLifecycleOwner.get().getLifecycle().removeObserver(lifecycleListener);

更多信息和示例可以在这篇优秀的文章中找到:

https://proandroiddev.com/detecting-when-an-android-app-backgrounds-in-2018-4b5a94977d5c

于 2019-04-02T07:34:56.870 回答
0

我遇到过同样的问题。当我的活动不处于前台模式时,我想显示推送通知。请通过以下代码,您将得到答案。

    Context ctx = context.getApplicationContext();

    ActivityManager am = (ActivityManager) context
            .getSystemService(ACTIVITY_SERVICE);

    // get the info from the currently running task
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);

    PackageManager pm = this.getPackageManager();

    try {
        /**
         * take fore ground activity name
         */
        ComponentName componentInfo = taskInfo.get(0).topActivity;
        if (printLog == true) {
            Log.d("Home", "CURRENT Activity ::"
                    + taskInfo.get(0).topActivity.getClassName());
            Log.d("Home", "Number Of Activities : "
                    + taskInfo.get(0).numRunning);
            Log.d("Home",
                    "Componenet Info : " + componentInfo.getPackageName());
            Log.d("Home",
                    "Componenet Info : " + componentInfo.getClassName());
        }
        /**
         * All activities name of a package to compare with fore ground
         * activity. if match found, no notification displayed.
         */
        PackageInfo info = pm.getPackageInfo(
                "<PackageName>",
                PackageManager.GET_ACTIVITIES);
        ActivityInfo[] list = info.activities;

        for (int i = 0; i < list.length; i++) {
              Log.d("TAG","Activity : "+list[i].name);
        }

    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }

要使用它,您必须在您的manifest文件中获得许可。

使用权限 android:name="android.permission.GET_TASKS"

如果我不能回答你的问题,请原谅我。

于 2012-12-26T18:34:22.383 回答
0

如果您需要知道应用程序是在后台运行的服务的后台还是前台(否则没有意义),那么您可以使用绑定,即 - 在所有活动上绑定到它 onResume , 并解除对所有活动 onPause 的绑定。然后在您的服务中,您不仅可以管理您的应用程序对用户的可见性,还可以随时管理哪些活动是打开的。当您使用 android 的 API 并依赖于 android 操作系统代码本身的正确性时,它也比静态变量(如果需要可以清理)更防泄漏和更稳定。

于 2014-04-28T17:08:59.087 回答