今天遇到一个很奇怪的问题,就是我们项目里的通知突然间失效了,具体表现是:通知栏能弹出通知提示,但是想通过它点击跳转到Activity确无法响应,也不消失,然后就抓耳挠腮的开始一点点debug调试找原因所在,始终无所收获。后来我又把项目里的有关通知的代码(一共也没有多少)单独写成一个demo,发现也还是不行。经历了各种百度,查资料,终无所或,后来找了个正常的demo,反复对比,一点点修改实验,终于被我找到了问题所在,下面我就开始讲述一下问题所在。
首先,先展示一下有问题的代码:
NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(mContext);
builder.setContentTitle(title);
builder.setContentText(content);
Notification n = builder.getNotification();
if (PublicUtils.ISDEMO) {
n.icon = R.drawable.icon_main;
} else {
n.icon = R.drawable.icon_main;
}
n.tickerText = title;
if (awoketype == 2) {// isSound表示需要声音提示
n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
} else if (awoketype == 1) {// 震动
n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
long[] vibrate = {0, 100, 200, 300}; // 自定义震动
n.vibrate = vibrate;
} else {//铃声加震动
n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
long[] vibrate = {0, 100, 200, 300}; // 自定义震动
n.vibrate = vibrate;
}
// n.sound = Uri.parse("file:///sdcard/test.mp3");//调用自定义声音
n.defaults |= Notification.DEFAULT_LIGHTS; // 调用系统默认的灯光
n.flags |= Notification.FLAG_AUTO_CANCEL; // 通知被点击后自动消除
n.flags |= Notification.FLAG_NO_CLEAR; // 点击'Clear'时,不清除该通知
//n.flags |= Notification.FLAG_; //让声音、振动无限循环,直到用户响应
n.when = System.currentTimeMillis();
Intent intent = new Intent(mContext, RelayActivity.class);
PendingIntent pi = PendingIntent.getActivity(mContext, id, intent, 0);
builder.setContentIntent(pi);
nm.notify(id, n);
问题代码就是这样,具体表现是:通知栏能弹出通知提示,但是想通过它点击跳转到Activity确无法响应,也不消失。
这段代码要是一行一行的去看的话,是一点问题都没有,所以我用debug断点调试许久,发现也没出现问题。百思不得其解,后来就百度了一个正确的demo,然后发现写法都大同小异,为什么我的就有问题呢,细心的我开始一行一行去对比,一点一点去尝试,后来发现我的notification声明的位置跟demo有所不同,然后我就去调换它的位置,把他挪到builder.setContentIntent之后,然后重新运行,奇迹发生了,居然可以了,应该是notification是依附于builder构建的,由于一开始builder的不完整即notification声明位置不恰当导致,问题就这么被解决了。
另外还要说一点,这样的写法,下拉通知的图标会显示不出来,需要builder.setSmallIcon(R.mipmap.ic_launcher);这样去设置。
到这里所有的问题都解决了,只是因为以前我们的项目是没有问题的,所以我不明白问题是出在了哪里,我就去以前分支上找答案,我们的项目是最近从eclipse迁移到studio上的,所以我终于在一起eclipse 的分支上发现了点有用的东西,以前分支上的代码是这样的:
NotificationManager nm = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = new Notification();
if (PublicUtils.ISDEMO) {
n.icon = R.drawable.icon_main;
}else{
n.icon = R.drawable.icon_main;
}
n.tickerText = title;
if (awoketype == 2) {// isSound表示需要声音提示
n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
} else if (awoketype == 1) {// 震动
n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
long[] vibrate = { 0, 100, 200, 300 }; // 自定义震动
n.vibrate = vibrate;
}else{//铃声加震动
n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
long[] vibrate = { 0, 100, 200, 300 }; // 自定义震动
n.vibrate = vibrate;
}
// n.sound = Uri.parse("file:///sdcard/test.mp3");//调用自定义声音
n.defaults |= Notification.DEFAULT_LIGHTS; // 调用系统默认的灯光
n.flags |= Notification.FLAG_AUTO_CANCEL; // 通知被点击后自动消除
n.flags |= Notification.FLAG_NO_CLEAR; // 点击'Clear'时,不清除该通知
//n.flags |= Notification.FLAG_; //让声音、振动无限循环,直到用户响应
n.when = System.currentTimeMillis();
Intent intent = new Intent(mContext, RelayActivity.class);
PendingIntent pi = PendingIntent.getActivity(mContext, id, intent, 0);
n.setLatestEventInfo(mContext, title, content, pi);
nm.notify(id, n);
发现以前的代码顺讯确实是这样,但是有一句话确不同,n.setLatesteEventInfo,我就又去百度这个方法,发现在最新的sdk23上,此方法已失效,原来谷歌废弃了它,所以才用Notification.builder来构建,结果应该是项目迁移的时候,小伙伴直接用Notification.builder进行了替换,而导致这个功能失效,坑了宝宝(/捂脸哭)。
在此写出来,希望大家都长些教训吧,同时也学习了新知识,意外的收获。
最后贴一下正确的代码:
NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(mContext);
builder.setContentTitle(title);
builder.setContentText(content);
Intent intent = new Intent(mContext, RelayActivity.class);
PendingIntent pi = PendingIntent.getActivity(mContext, id, intent, 0);
builder.setContentIntent(pi);
builder.setSmallIcon(R.drawable.icon_main);
Notification n = builder.getNotification();
if (PublicUtils.ISDEMO) {
n.icon = R.drawable.icon_main;
} else {
n.icon = R.drawable.icon_main;
}
n.tickerText = title;
if (awoketype == 2) {// isSound表示需要声音提示
n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
} else if (awoketype == 1) {// 震动
n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
long[] vibrate = {0, 100, 200, 300}; // 自定义震动
n.vibrate = vibrate;
} else {//铃声加震动
n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
long[] vibrate = {0, 100, 200, 300}; // 自定义震动
n.vibrate = vibrate;
}
// n.sound = Uri.parse("file:///sdcard/test.mp3");//调用自定义声音
n.defaults |= Notification.DEFAULT_LIGHTS; // 调用系统默认的灯光
n.flags |= Notification.FLAG_AUTO_CANCEL; // 通知被点击后自动消除
n.flags |= Notification.FLAG_NO_CLEAR; // 点击'Clear'时,不清除该通知
//n.flags |= Notification.FLAG_; //让声音、振动无限循环,直到用户响应
n.when = System.currentTimeMillis();
nm.notify(id, n);