我有一个包含四个活动的应用程序,在应用程序中,用户会发现自己不断地浏览这四个活动。该应用程序还在后台有一个正在进行的服务,该服务显示一个状态栏通知,并监听将出现在通知上的内容的更改。
目前,只要用户启动需要显示通知的操作,服务就会显示通知,因此,即使您仍在使用应用程序,也会显示通知。期望的场景是仅在用户离开应用程序时才显示通知。
我试图覆盖这样的生命周期方法:
@Override
protected void onPause() {
Intent intent = new Intent();
intent.setAction(MyService.ACTION_DISPLAY_PENDING_NOTIFICATION);
sendBroadcast(intent);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
Intent intent = new Intent();
intent.setAction(MyService.ACTION_CANCEL_NOTIFICATION);
sendBroadcast(intent);
}
服务是这样的:
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_DISPLAY_PENDING_NOTIFICATION)) {
showNotification();
}
else if (action.equals(ACTION_CANCEL_NOTIFICATION)) {
mNotificationManager.cancel(mNotId);
}
}
这个,有效。但是,由于在用户导航离开活动时随时发送意图,因此当用户导航通过 4 个活动时,我会遇到不希望的行为和轻微的性能下降。即使从活动 A 转到活动 B,或 4 个活动中的任何组合,该服务也会尝试显示通知。
通知会立即取消,因为当新的 Activity B 启动时,它会在onResume期间调用 mNotificationManager.cancel(mNotifId) ,但是通知是在离开 Activity A 时被告知服务被告知这样做时构建并显示了几分之一秒的. 这是我想要解决的行为,而不是不必要地构建和显示此通知,
有什么方法可以知道用户何时将活动离开另一个应用程序,即主页等;但不在应用程序本身内?
编辑:
澄清一下,在 onPause 方法期间活动必须检查两件事,
a) 前台是否有任何先前的活动?为什么?因为用户可以通过按返回来导航出活动,这意味着将显示堆栈上的最后一个活动。为了检查这一点,DennisDrew 的答案会起作用,我们可以这样检查:
if(!ForegroundHelper.activityExistsInForeground()){
//show your notification
}
但这不是用户可以导航出活动的唯一方式,用户还可以按下 HomeKey,在这种情况下,无论activityExistsInForeground()
评估为真还是假,都应该显示通知。
b) 用户是否要去应用程序中的另一个活动?例如,用户在 Activity A 上,A 是目前前台唯一的 Activity,用户单击启动 Activity B 的 UI 元素。尽管activityExistsInForeground()
评估为 false,但用户并没有离开应用程序,他正在启动一个新实例以前不在freground 上的活动。
我尝试添加诸如private boolean launchingNewActivity = false
默认值之类的标志,并将标志设置为true
当我知道我要去另一个活动时,例如在我的列表视图上单击一个项目时:
litview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
launchingNewActivity = true
startActivity2(arg2);
}
});
然后在 onPause 期间检查:
@Override
protected void onPause() {
if(!ForegroundHelper.activityExistsInForeground() && launchingNewActivity){
//show your notification
}
但是这样做,它永远不会显示通知,不知何故,双重检查总是默认为假。