安卓:仅在离开应用程序时显示 Staus Bar 通知



我有一个包含四个活动的应用程序,在该应用程序中,用户会发现自己不断浏览这四个活动。该应用程序还在后台有一个正在进行的服务,该服务显示状态栏通知,并侦听随后将显示在通知上的内容更改。

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

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

    @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()的计算结果为 true 还是 false,都应显示通知。

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);
        }           
    });

然后在暂停期间检查:

@Override
protected void onPause() {
    if(!ForegroundHelper.activityExistsInForeground() && launchingNewActivity){
    //show your notification        
}

但是这样做,它永远不会显示通知,不知何故,双重检查始终默认为 false。

如果使用单例引用会怎样?你可以创建一个这样的类:

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
}

顺便说一句,我从来没有做过这样的事情,所以我不知道它是否会完全按照我的编码工作......但让我知道这是否有帮助。

我为此所做的是扩展了应用程序类,并保留了我将在每个onResume/onPause方法中设置的"topActivity",如下所示:

public class myApp extends Application{
   private Activity topActivity;
}

现在在每个活动中

@Override
protected void onResume() {
((myApp) getApplication()).setOnTopActivity(this);
}
@Override
    protected void onPause() {
        ((myApp) getApplication()).setOnTopActivity(null);
        super.onPause();
    }

这样,当应用不可见时,topActivity 为 null。因此,在显示通知之前,只需检查 topActivity==null。如果是,你的应用不在前台,你可以显示你的通知。

如果您无权访问应用程序类,则始终可以静态方式存储此值:)

相关内容

  • 没有找到相关文章

最新更新