在Android收到通知,点击跳转的时候可能遇到一些问题。
1、onNewIntent()
onNewIntent()介绍:当我们设置activity的启动模式是singleTop的时候,再次启动这个activity就会走onNewIntent()–onResume()这样的流程,而不会再走onCreate()方法
/**
* This is called for activities that set launchMode to "singleTop" in
* their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
* flag when calling {@link #startActivity}. In either case, when the
* activity is re-launched while at the top of the activity stack instead
* of a new instance of the activity being started, onNewIntent() will be
* called on the existing instance with the Intent that was used to
* re-launch it.
*
* <p>An activity will always be paused before receiving a new intent, so
* you can count on {@link #onResume} being called after this method.
*
* <p>Note that {@link #getIntent} still returns the original Intent. You
* can use {@link #setIntent} to update it to this new Intent.
*
* @param intent The new intent that was started for the activity.
*
* @see #getIntent
* @see #setIntent
* @see #onResume
*/
protected void onNewIntent(Intent intent) {
}
2、问题1:当通过Intent跳转的时候从Intent中取出的数据不是我们通过Intent传递的值。
示例:当我们收到通知的时候通过intent携带
intent.putExtra(“data”, “msg”);但在activity中取出来的并不是我们传递的数据。而是老的数据(这个数据是我们以前用过的);
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("data", "msg");
PendingIntent pIntent = PendingIntent.getActivity(context, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
mBuilder.setContentIntent(pIntent);
mNotificationManager.notify(pb.getId(), mBuilder.build());
在activity中
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String data = intent.getStringExtra("data");
System.out.println("notify-----" + data);
}
解决办法:
在onNewIntent()中加上setIntent(intent);The new Intent object to return from getIntent(通过设置返回给我们最新的intent)
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
String data = intent.getStringExtra(Constants.DATA);
System.out.println("notify-----" + data);
if (StringUtils.isBlank(data)) {
return;
}
if (data.equals(Constants.DATA_MSG)) {
setRightFragment(new ChatListFragment());
} else {
setRightFragment(new PatientListFragment());
}
}
2、问题1:设置了onNewIntent ()中的setIntent(intent); 仍然没有有取出最新的intent是携带的参数。
我在通知中判断不同的通知类型,产生不同的通知,代码如下,发现传递的产生一直为null,但我在intent中的确携带参数了。
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void updateNotification(Context context, PushBean pb) {
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context);
System.out.println("--------type---" + pb.getType());
if (pb.getType().equals("1")) {
// 血糖推送
mBuilder.setContentTitle("血糖告警")
.setContentText(pb.getMsg())
.setTicker("收到血糖告警信息!")
.setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setDefaults(
Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setSmallIcon(R.drawable.notification_logo);
if ("-1".equals(pb.getCode())) {
mBuilder.setSound(Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.low));
} else if ("1".equals(pb.getCode())) {
mBuilder.setSound(Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.high));
}
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(Constants.DATA, Constants.DATA_BLOOD);
PendingIntent pIntent = PendingIntent.getActivity(context, 0,
intent, 0);
mBuilder.setContentIntent(pIntent);
mNotificationManager.notify(pb.getId(), mBuilder.build());
} else {
// 医院互动
mBuilder.setContentTitle("医患互动").setContentText(pb.getMsg())
.setTicker("收到医患互动信息!").setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_DEFAULT)
.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.notification_logo);
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(Constants.DATA, Constants.DATA_MSG);
PendingIntent pIntent = PendingIntent.getActivity(context, 0,
intent, 0);
mBuilder.setContentIntent(pIntent);
mNotificationManager.notify(pb.getId(), mBuilder.build());
}
}
后来发现问题是在PendingIntent上
当通过getActivity设置时
public static PendingIntent getActivity(Context context, int requestCode,
Intent intent, int flags) {
return getActivity(context, requestCode, intent, flags, null);
}
第一个参数:上下文
第二个参数:requestCode
当我们使用Flags为PendingIntent.FLAG_UPDATE_CURRENT时如果没有传递requestCode时,那么通知来了,我们点击最后一个会跳转,而点击前面的都不会再跳转了
解决办法:
设置一个 int msgTag,在每次消息来的时候msgTag++;把这个值给requestCode这样值 不同,多个通知也都能响应点击事件了。
第三个参数:intent;
第四个参数:标记 FLAG_CANCEL_CURRENT 和FLAG_UPDATE_CURRENT
/**
* Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
* {@link #getService}: if the described PendingIntent already exists,
* the current one is canceled before generating a new one. You can use
* this to retrieve a new PendingIntent when you are only changing the
* extra data in the Intent; by canceling the previous pending intent,
* this ensures that only entities given the new data will be able to
* launch it. If this assurance is not an issue, consider
* {@link #FLAG_UPDATE_CURRENT}.
*/
public static final int FLAG_CANCEL_CURRENT = 1<<28;
/**
* Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
* {@link #getService}: if the described PendingIntent already exists,
* then keep it but its replace its extra data with what is in this new
* Intent. This can be used if you are creating intents where only the
* extras change, and don't care that any entities that received your
* previous PendingIntent will be able to launch it with your new
* extras even if they are not explicitly given to it.
*/
public static final int FLAG_UPDATE_CURRENT = 1<<27;
Flags为PendingIntent.FLAG_CANCEL_CURRENT,则只有最后一次PendingIntent有效,之前的都无效了。(只有点击最后一有个通知才会效,点击以前人都不会跳转)
Flags为PendingIntent.FLAG_UPDATE_CURRENT,对于FLAG_UPDATE_CURRENT,如果上面的num为常量, 则所有对应的Intent里面的extra被更新为最新的, 就是全部为最后一次的。
相反,如果requestCode每次不一样,则里面的Inent的数据没被更新(也就是说,如果每个requestCode不一样时,我们点击不同的通知才会做出跳转)。
正确的代码如下:
public class NotificationReceiver extends BroadcastReceiver {
private int msgTag = 0;
NotificationManager mNotificationManager;
@Override
public void onReceive(Context context, Intent intent) {
if (Constants.ACTION_PUSH.equals(intent.getAction())) {
String msg = intent.getExtras().getString("contacts");
System.out.println("收到通知------");
LogUtils.i("pushStatus", "收到的广播:" + msg);
if (StringUtils.isNotBlank(msg)) {
String[] result = msg.split(";/");
Gson gson = new Gson();
PushBean pb = gson.fromJson(result[2], PushBean.class);
if (StringUtils.isNotBlank(result[0])) {
pb.setId(Integer.parseInt(result[0]));
}
updateNotification(context, pb);
}
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void updateNotification(Context context, PushBean pb) {
msgTag++;
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context);
System.out.println("--------type---" + pb.getType());
System.out.println("收到通知时msgTag=====" + msgTag);
if (pb.getType().equals("1")) {
// 血糖推送
mBuilder.setContentTitle("收到一个血糖通知")
.setContentText(pb.getMsg())
.setTicker("收到血糖告警信息!")
.setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setDefaults(
Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setSmallIcon(R.drawable.notification_logo);
if ("-1".equals(pb.getCode())) {
mBuilder.setSound(Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.low));
} else if ("1".equals(pb.getCode())) {
mBuilder.setSound(Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.high));
}
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(Constants.DATA, Constants.DATA_BLOOD);
PendingIntent pIntent = PendingIntent.getActivity(context, msgTag,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pIntent);
mNotificationManager.notify(pb.getId(), mBuilder.build());
} else {
// 医院互动
mBuilder.setContentTitle("医患互动").setContentText(pb.getMsg())
.setTicker("收到医患互动信息!").setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_DEFAULT)
.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.notification_logo);
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(Constants.DATA, Constants.DATA_MSG);
PendingIntent pIntent = PendingIntent.getActivity(context, msgTag,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pIntent);
mNotificationManager.notify(pb.getId(), mBuilder.build());
}
}
}