当前位置: 移动技术网 > IT编程>移动开发>Android > 关于Android中点击通知栏的通知启动Activity问题解决

关于Android中点击通知栏的通知启动Activity问题解决

2019年07月24日  | 移动技术网IT编程  | 我要评论

英镑兑换人民币汇率,浩瀚的反义词,洛克王国黑珍珠航海令

前言

最近遇到一个很奇葩的问题,终于解决了,所以想着记录一下,方便大家或者自己以后有需要的时候可以参考学习。

问题场景

用小米手机使用小米推送一条消息,然后点击通知栏中的消息启动应用,然后进入会话的activity。应用启动后,如果当前界面不是会话界面,那么新消息会在通知栏显示消息提醒,然后点击会话消息后却进不了会话的activity,即点击了通知栏通知后,系统都没有启动指定activity的意思,没有看到系统启动activity的log,到是会看到系统处理这个activity的影子。

这个指定的activity不是会话的activity,而是在androidmanifest.xml文件中指定android.intent.category.launcher的activity a。也就是说有会话消息都是先从这个a开始,然后把数据往后面的activity传。

这里显示通知有两种方式,一种是由手机系统在通知栏弹出,比如小米手机上使用小米推送,华为手机上使用华为推送,另外一种是由应用的远程进程弹出。

启动应用的第一个activity a也有两种方式,一种是直接通过new来构造一个intent,然后传入activity a的class;另外一种是通过context.getpackagemanager().getlaunchintentforpackage(context.getpackagename())来获取启动的activity a的intent。然后调用pendingintent.getactivity()方法,将得到的intent传入。

那么问题来了,如果是点击系统弹出的通知栏或者远程进程弹出的通知栏,如果只是使用其中一种启动方式启动应用,那么在应用启动后,点击通知栏中由后台远程进程弹出的新消息通知,这个时候就不能进入会话的activity。从系统的日志来看,没有启动activity,只是对activity做了处理。

可能有人会想到是不是要加一个intent.flag_activity_new_task标识,因为在getlaunchintentforpackage()方法中加了这个标识。

最后测试发现,只要应用没有被启动,不管是点击系统弹出的通知栏还是远程进程弹出的通知栏,如果再收到新消息通知,再点击通知栏,就能进入会话activity了。那只要判断应用中是否有activity被启动就ok了,貌似问题可以解决了。

问题解决

于是用了下面的逻辑来判断是否有前台activity在运行。

/**
 * 判断ui进程是否正在运行
 * @return 返回true表示正在运行,否则没有运行
 */
public static boolean isforegroundrunning() {
 activitymanager am = (activitymanager) eimcloud.getcontext().getsystemservice(context.activity_service);
 list<activitymanager.runningappprocessinfo> list = am.getrunningappprocesses();
 if (list != null) {
  for (activitymanager.runningappprocessinfo info : list) {
   if (info.importance == activitymanager.runningappprocessinfo.importance_foreground
  && eimcloud.getcontext().getpackagename().equals(info.processname)) {
  return true;
   }
  }
 }

 return false;
}

拓展

但是上面的方法在小米手机上凑效了,但在华为手机上还是有问题,即使同样的场景。华为又坑爹了!

于是开始从上面的activitymanager.runningappprocessinfo类中的importance变量的状态入手,然后测试各种场景可能出现的变量值,结果发现效果不尽人意,有些场景问题依旧。

最后,又换种思路:不从activity a开始启动应用,换个activity b,也就是在调用pendingintent.getactivity()方法传入intent对象使用b的class。启动b会发现应用没有被初始化,则跳转到a执行初始化,然后再走正常流程。

再针对各种场景以及各种机型测试,发现问题解决。从上面可以看出,虽然不懂背后原理,但解决问题的思路一定要广,特别是在急着发版本的时候,不要在一棵树上吊死。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网