【发布时间】:2015-04-29 17:14:48
【问题描述】:
我有一个后台服务在做一些工作——按时间间隔检索用户位置(使用startService 启动)。一旦达到特殊条件,我想做以下事情:
- 如果应用程序在前台,则启动特定活动。
- 如果应用程序不在前台或未关闭,则显示将在点击时启动所需活动的通知。
例如,我知道如何显示通知以及如何使用广播接收器处理来自服务器的意图。但是如何确定我的应用程序是否在前台?或者您可以提出完整的更好的解决方案?
【问题讨论】:
我有一个后台服务在做一些工作——按时间间隔检索用户位置(使用startService 启动)。一旦达到特殊条件,我想做以下事情:
例如,我知道如何显示通知以及如何使用广播接收器处理来自服务器的意图。但是如何确定我的应用程序是否在前台?或者您可以提出完整的更好的解决方案?
【问题讨论】:
我确定我的应用程序是否在前台
有几种方法可以找出前面的内容,但我实际上更喜欢自己跟踪它(因为这有助于我在需要时应用额外的逻辑)。另外,这是非常简单的任务。要做到这一点,您需要在某处使用基于int 的静态计数器(如果您有一个对象,则可以使用您的Application 对象,或者在其他地方拥有它,这并不重要)。在每个Activity 的onResume() 中,您将计数器加一,在onPause() 中,您将其减一。如果计数器等于0,那么您的任何活动都不是在前台,所以从您的角度来看,您在后台并发布通知。为简单起见,我总是在我的 ActivityBase 课程中这样做,我的所有活动都会扩展。
如果您不想自己跟踪,可以使用ActivityManager 来查看当前在前台的情况:
public boolean isAppInForeground() {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = am.getRunningTasks(Integer.MAX_VALUE);
return (services.get(0).topActivity.getPackageName().toString()
.equalsIgnoreCase(getPackageName().toString()));
}
但这需要在您的清单中输入<uses-permission android:name="android.permission.GET_TASKS" />,因此并不总是受欢迎的。
【讨论】:
ActivityManager 的方法。至于您的问题:如果您的应用程序使用任何对象子类,您可以使用 Application 对象子类,因为每个应用程序总是有一个 Application 对象。或者,您可以将您的计数器保留在 Singleton 中,但如果您在应用程序中使用 Threads,请see this question。
Marcin 的答案的替代方法是将您的活动绑定和取消绑定到服务。这将允许在该绑定存在时服务和活动之间进行通信,并且服务将知道能够处理该场景的活动当前是否可用 - 例如。如果用户处于某个重要过程的中间(例如接受 T&C/EULA 或其他),您可能不想直接启动 Activity,因此服务可以告诉 Activity 发生了事件,但 Activity 可以响应事件正确。
【讨论】:
startService 和binsService 启动服务,如果活页夹处于活动状态,则向其发送信息并显示通知?