下面来一段代码,引出今天的梗
1 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
上面的代码就是最基本的消息通知,然后启动相应的界面,现在世面上大多数也都是这么写的,但是最近却栽在这个坑上了,为啥这么说,因为当我们消息推送的时候在其他机型这样写都是OK的,唯独在华为上面,点击消息启动栏没有任何反应,也不闪退,也不给我们答案,就是通知状态没有了。纠结了一阵子,今天终于。。。。
我们先来看一下,作用于此事件的幕后黑手究竟是谁,上面的代码一目了然,PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags),nm.notify(0, mNotification);就是这两个方法在搞怪,我们来看看里面的参数,PendingIntent.getActivity)官方的解释是这样的
Retrieve a PendingIntent that will start a new activity, like calling Context.startActivity(Intent). Note that the activity will be started outside of the context of an existing activity, so you must use the Intent.FLAG_ACTIVITY_NEW_TASK launch flag in the Intent.
主要的意思就是使用PendingIntent来启动一个Activity,就像用Context.startActivity(Intent)来启动一个Activity一样,注意这里的activity将是上下文之外现有的activity,所以你必须使用Intent.FLAG_ACTIVITY_NEW_TASK标记位来启动一个intent。
这里面的第一个,第三个参数这里不打算细说了。
1 | * this PendingIntent should start context The Context in which |
摘自源码,当我们点进去getActivity方法时是这样的
1 | public static PendingIntent getActivity(Context context, int requestCode, |
第四个参数Flag我挨个换了一遍还是不行,排除法,最后剩下requestCode了,可是网上都是这么写的啊,不然,就是他的原因。我们可以从源码中可以看出来,我们把requestCode传进去之后,重新传给了IIntentSender对象,看源码涉及到IPC机制,贴出getIntentSender()源码
1 | public IIntentSender getIntentSender(int type, |
这里首先获取Parcel对象,Parcel.obtain(),然后将我们传递过来的参数打包到Parcel对象中,parcel.write(),最后将我们打包好的数据发送出去 mRemote.transact(),最后回收parcel对象,data.recycle();reply.recycle();
猜测应该是sender用requestCode来区分不同的PendingIntent对象,然后对应。因为之前我们传递的都是0,所以这里我们将requestCode的值改为每条消息都不一样就好了。这里也要记住,getActivity中requestCode和notiy中的id要保持一致,我将这里改成了
1 | PendingIntent mPendingIntent = PendingIntent.getActivity(context, (int)System.currentTimeMillis()/1000, intent, PendingIntent.FLAG_UPDATE_CURRENT); |
这样就解决问题了。
版权声明:
除非注明,本博文章均为原创,转载请以链接形式标明本文地址。