Android:仅在离开应用程序时显示状态栏通知

时间:2013-02-02 14:01:06

标签: android android-notifications

我有一个包含四个活动的应用程序,在应用程序中,用户会发现自己经常浏览4个活动。该应用程序还在后台提供持续服务,该服务显示状态栏通知,并侦听随后将显示在通知上的内容更改。

目前,只要用户启动需要显示通知的操作,服务就会显示通知,因此,即使您仍在使用该应用程序,也会显示通知。所需方案是仅在用户导航出应用程序时显示通知。

我试图覆盖这样的生命周期方法:

    @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个活动中的任何组合,该服务也将尝试显示通知。

通知会立即取消,因为当新的活动B启动时,它会在 onResume 期间调用mNotificationManager.cancel(mNotifId),但是通知已经构建并显示了几分之一秒作为离开活动A时,服务被告知这样做。这是我想要解决的行为,而不是不必要地构建和显示此通知,

有什么方法可以让我知道用户何时将活动转移到另一个应用程序,即主页等;但不在申请本身内?

修改

为了澄清,在onPause方法期间,活动必须检查两件事,

a)前景中是否有任何先前的活动?为什么?因为用户可以通过按回导航出活动,这意味着将显示堆栈上的最后一个活动。为了检查这一点,DennisDrew的答案是可行的,我们可以这样检查:

if(!ForegroundHelper.activityExistsInForeground()){
//show your notification
}

但这不是用户离开活动的唯一方式,用户也可以按HomeKey,在这种情况下,无论activityExistsInForeground()评估为真还是假,都应显示通知。

b)用户是否要去应用程序中的其他活动?例如,用户在活动A上,A是前台的唯一活动,用户点击启动活动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        
}

但是这样做,从不显示通知,不知怎的,双重检查总是默认为false。

1 个答案:

答案 0 :(得分:3)

如果您使用单身人士参考怎么办?你可以创建一个类:

public static class ForegroundHelper {
    public static boolean[] activityStates = new boolean{false, false, false, false};
    public static final int ACTIVITY_A = 0;
    public static final int ACTIVITY_B = 1;
    public static final int ACTIVITY_C = 2;
    public static final int ACTIVITY_D = 3;

    public static boolean activityExistsInForeground(){
        for(boolean b : activityStates){
            if(b)
                return true;
        }

        return false;
    }
}

然后,在每个活动的onResume()中执行:

//For your first activity (Activity A)
ForegroundHelper.activityStates[ForegroundHelper.ACTIVITY_A] = true;

在每个活动的onPause()中执行:

ForegroundHelper.activityStates[ForegroundHelper.ACTIVITY_A] = false;

然后在每个活动的onStop()中执行:

if(!ForegroundHelper.activityExistsInForeground()){
    //show your notification
}

顺便说一句,我从来没有做过这样的事情,所以我不知道它是否会像我编码那样完全正常...但是如果这有帮助请告诉我。