如何知道我的Android应用程序是否可见?

Phi*_*ach 18 android background foreground

我有一个计时器,当它结束时开始通知.但我想仅在应用程序当前不可见的情况下使用notificationManager发出通知,并在应用程序处于前台时显示计时器结束时显示alertDialog.

我已经尝试过这个:

ActivityManager actMngr = (ActivityManager) ValeoMobileApplication.getContext().getSystemService(Activity.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = actMngr.getRunningAppProcesses();
Tools.log("TimerBroadcastReceiver", "onReceive", "All running processes are listed below :");
for (RunningAppProcessInfo pi : runningAppProcesses) {
    //Check pi.processName and do your stuff
    //also check pi importance - check if process is in foreground or background
    Tools.log("TimerBroadcastReceiver", "onReceive", pi.processName + " importance = "+pi.importance);
    if(pi.processName.equalsIgnoreCase("MY_APP_PROCESS_NAME")){
        if (pi.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            isApplicationInForeground = true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但似乎应用程序是否为前景并不重要.我怎样才能做到这一点?

Com*_*are 25

但我想仅在应用程序当前不可见的情况下使用notificationManager发出通知,并在应用程序处于前台时显示计时器结束时显示alertDialog.

使用有序广播,活动具有高优先级接收器(如果它在前台),加上清单注册接收器用于不在前台的情况.

这是一篇概述这种技术的博客文章.

更新2018-01-04:上述方法有效,但它涉及系统广播,对于大多数(单进程)应用程序来说,这不是一个很好的选择.可以使用事件总线(LocalBroadcastManagergreenrobot的EventBus),具有更好的性能和安全性.请参阅使用该示例应用程序LocalBroadcastManager使用greenrobot的EventBus这个示例应用程序,它们都实现了这种模式.

  • 如果您的主要活动是启动另一项新活动,则此方法无法正常运行.那时,当onPause被触发时,将发生取消注册.但是,从最终用户的角度来看,应用程序仍然可见. (3认同)

Shl*_*blu 10

您可以通过以下方式检测您的应用是否可见:

在你的所有你的Activity集合中:

@Override
protected void onResume() {
    super.onResume();

    myVisibilityManager.setIsVisible(true);
}

@Override
protected void onPause() {
    myVisibilityManager.setIsVisible(false);

    super.onPause();
}
Run Code Online (Sandbox Code Playgroud)

(这可能会导致您为实现此行为的所有活动定义超类)

然后创建一个VisibilityManager(这个是非常基本的,你可能需要更先进的东西):

public class VisibilityManager {
    private boolean mIsVisible = false;

    public void setIsVisible(boolean visible) { 
         mIsVisible = visible; 
    }

    public boolean getIsVisible() {
         return mIsVisible;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在你的计时器线程中,当倒计时达到零时:

if (VisibilityManager.getIsVisible()) {
    showAlertDialog();
}
else {
    showNotification();
}
Run Code Online (Sandbox Code Playgroud)

编辑:但我更喜欢本页描述的CommonsWare方法.它更优雅.