确定前台的应用程序是否是不受欢迎的?

问题描述 投票:3回答:4

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

需要明确的是:后台应用程序的定义(如我所见)是: 应用程序没有任何活动被调用onStart()方法,并没有调用onStop()方法。那是因为活动只在那个时候在生命周期中对用户可见。

从另一方面 -

  • 似乎Google不希望应用程序对主页按钮作出反应(它不是API的一部分)
  • 对“root / main”活动中的onBackPressed()作出反应作为离开Activity的指标当然不是​​一个好主意(因为很多用户使用主页按钮,而不是后退按钮)
  • API中没有方法可以确定app是否为前景(根据我的定义..)

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

我知道我可以做的是确定应用程序是否为前景在此线程中描述 - How to detect when an Android app goes to the background and come back to the foreground

但正如@Emil所说 - 它需要特殊许可,或者需要一些棘手的逻辑,这些逻辑很快就会成为维护的问题,并且它闻起来像是糟糕的方法(虽然这就是我现在正在做的事情,因为我没有更好的想法。 ..)

我的问题基本上是:

  • 有充分理由没有这样的API方法吗?
  • 是否考虑应用程序是否为前景是一种不好的方法?
  • 有没有其他方法可以知道应用程序是否是前景?
android activity-lifecycle application-lifecycle
4个回答
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


5
投票

如果应用程序是前景或不是一个坏方法,考虑到?

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

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

您可以将此方案粗略地分为两组:

  1. 您希望在更改前景/后台状态时立即采取操作的情况
  2. 发生其他事件的情况(AlarmManager警报,传入系统广播等),此时你想根据你是否在前台采取不同的行动

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

在后一种情况下,ordered broadcast可能是有用的。


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文件的权限。

uses-permission android:name =“android.permission.GET_TASKS”

请原谅我,如果我无法得到您的问题。


0
投票

如果您需要知道应用程序是在背景上运行的服务的背景或前景(否则没有意义),那么您可以使用绑定,即 - 绑定到您的所有活动onResume ,并取消暂停所有活动onPause。然后,在您的服务中,您不仅可以管理应用程序对用户的可见性,还可以随时管理哪些活动。它也是防漏的,比静态变量更稳定(如果需要可以清理),因为你正在使用android的API并依赖于android OS代码本身的正确性。

© www.soinside.com 2019 - 2024. All rights reserved.