判断应用的activity是否在前后台运行
背景:最近项目中做关于聊天的消息推送,在测试时发现了一个反人类的异常:在聊天窗口和他人聊天时通知栏居然有一条一条的消息源源不断的推送了过来/(ㄒoㄒ)/~~,如何在聊天时关闭当前聊天消息的推送呢,这就是今天要讨论的内容啦!
当时想到了一种简单粗暴的解决方案,进入聊天界面直接把推送给关了,退出聊天窗口时再注册一次重新打开推送就ok了,但是问题又来了,推送它不只是聊天一种,还有其他的比如在天猫一家店铺买了手机贴膜,又想在另一家店铺相中了好看的手机壳,正在向手机壳家询问是否有优惠时手机贴膜发货了,这个发货可是得通知主人的,所以这个方案PASS!!!
然后又想到了判断推送过来的信息是否是聊天信息,再判断包含的商家的id是否是正在聊天的商家的id,是的话不显示这条推送,万事大吉:-D!!!
说的有点远,下面说下实现方式,首先获取ActivityManager
对象
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
接着获取app的任务列表
List<ActivityManager.AppTask> taskList = manager.getAppTasks();
然后foreach遍历任务中的AppTask
这个静态内部类并获取另一个静态内部类RecentTaskInfo
,这个类才是我们获得栈顶activity的关键类,通过RecentTaskInfo
的对象获取topActivity
,
判断这个topActivity
的className是否和当前的聊天界面类名相同就ok了,下面是循环方法
for (ActivityManager.AppTask task : taskList) {
ActivityManager.RecentTaskInfo taskInfo = task.getTaskInfo();
String className = taskInfo.topActivity.getClassName();
String packageName = taskInfo.topActivity.getPackageName();
textView.setText("className=" + className + "\n" +
"packageName=" + packageName + "\n" +
"activityName=" + SecondActivity.class.getName());
}
这个RecentTaskInfo
还能做很多的事,如获得任务中activity的数量、第一个启动的activity等等。
当然了,ActivityManager
这个类的作用还不止于此,还可以使用它判断app是否在后台运行:
List<ActivityManager.RunningAppProcessInfo> processInfoList = manager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : processInfoList) {
if (processInfo.processName.startsWith(PKG_NAME)) {
boolean isBackGround =
processInfo.importance != IMPORTANCE_FOREGROUND
&& processInfo.importance != IMPORTANCE_VISIBLE;
Log.i(TAG, "app处于后台=" + isBackGround);
}
}
通过判断importance
是否等于IMPORTANCE_FOREGROUND
和 IMPORTANCE_VISIBLE
,这两个值的意思是app是在前台且处于可见状态。其他状态请看源码解释

以上方法是SDK最新判断方法,之前的判断方法谷歌为了系统安全已经弃用了,学会查看源码是学习android最有效的手段,希望大家一起
Read The Fucking Source Code
共同提高进步吧_