检测应用程序是否在前台有很多原因。例如 - 作为GCM / C2DM推送通知的触发器 - 当应用程序是前台和后台时,许多应用程序将有充分的理由实现不同的行为。其他原因可能是 - 淘汰消耗宝贵资源的服务,例如在后台任务中查询服务器。
需要明确的是:后台应用程序的定义(如我所见)是:
应用程序没有任何活动被调用onStart()
方法,并没有调用onStop()
方法。那是因为活动只在那个时候在生命周期中对用户可见。
从另一方面 -
onBackPressed()
作出反应作为离开Activity
的指标当然不是一个好主意(因为很多用户使用主页按钮,而不是后退按钮)如果我没有错过API中的某些内容,而且确实如此 - 为什么没有原因可以轻松确定应用程序是否为前景???? !!!!
我知道我可以做的是确定应用程序是否为前景在此线程中描述 - How to detect when an Android app goes to the background and come back to the foreground
但正如@Emil所说 - 它需要特殊许可,或者需要一些棘手的逻辑,这些逻辑很快就会成为维护的问题,并且它闻起来像是糟糕的方法(虽然这就是我现在正在做的事情,因为我没有更好的想法。 ..)
我的问题基本上是:
使用新的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
如果应用程序是前景或不是一个坏方法,考虑到?
考虑前景与背景是合理的。
有没有其他方法可以知道应用程序是否是前景?
您可以将此方案粗略地分为两组:
AlarmManager
警报,传入系统广播等),此时你想根据你是否在前台采取不同的行动在前一种情况下,onUserLeaveHint()
是您最可靠的简单选择。我无法保证它将涵盖所有情况,但它应该处理HOME场景,例如。您也可以在静态数据成员中维护已启动活动的引用计数,并尝试使用它。
在后一种情况下,ordered broadcast可能是有用的。
我遇到过同样的问题。我希望在活动未处于前台模式时显示推送通知。请仔细阅读以下代码,您将得到答案。
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”
请原谅我,如果我无法得到您的问题。
如果您需要知道应用程序是在背景上运行的服务的背景或前景(否则没有意义),那么您可以使用绑定,即 - 绑定到您的所有活动onResume ,并取消暂停所有活动onPause。然后,在您的服务中,您不仅可以管理应用程序对用户的可见性,还可以随时管理哪些活动。它也是防漏的,比静态变量更稳定(如果需要可以清理),因为你正在使用android的API并依赖于android OS代码本身的正确性。