今天遇到一个关于Notification跳转到Activity的小问题,起初运行的时候,点击Notification上的按钮,跳转到相应的Activity,之后发现当有多个Notification时,把每个Notification上的按钮都点击一遍,出现了多个相同的Activity!
于是乎,就写了这篇文章。跟大家一起探讨一下Notification到Activity的问题!
首先,我们在MainActivity中添加一个Button,每次点击该Button弹出不同的Notification,代码如下:
PendingIntent pendingIntent= PendingIntent.getActivity(
context,
request_code++,
intent,
0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setContentTitle("Notification")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("ToActivity")
.setPriority(Notification.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification note = mBuilder.build();
manager.notify(number++,note); //notificationId每次递增1
注意:①代码中PendingIntent的第二个参数request_code++表示PendingIntent发送方的请求码,此处改变请求码防止pendingIntent重复
②代码中 manager.notify(number++,note),如果notify的第一个参数id是常量,那么多次调用notify只能弹出一个通知,后续的通知会把前面的通知完全替代掉,而如果每次id都不同,那么多次调用notify会弹出多个通知。
想要显示多个不同的Notification,则NotificationManager.notify(int id,Notification note)的第一个参数id必须每次都不同,这里我们通过number++的方式递增。
同时,我们PendingIntent.getActivity()的第四个参数为PendingIntent.FLAG_UPDATE_CURRENT,表示当描述的Intent有更新的时候需要用到这个flag去更新你的描述。如果所有的Intent都用用一个request_code,那么所有的Intent都会受到影响,导致所有的Intent传递的数据相同,所以这里PendingIntent.getActivity的第二个参数request_code也用递增进行改变,用来标识不同的Intent.
在SecondActivity中,接收Intent传来的参数number并显示到textView上。
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ");
Intent intent = getIntent();
int notificationId = intent.getIntExtra("data",-1);
mTextView.setText("notificationId = "+notificationId);
}
接下来运行一下,先点击两次button,显示两个通知
随后分别点击第一个通知和第二个通知,出现两个SecondActivity页面
默认情况下,两个Activity在同一个Task中,需要点击两次返回按钮才能回到MainActivity
要想只显示一个SecondActivity,可以通过Intent或者android:launchMode设置,这里我们只用第一种。
只需要给Intent添加Flag即可,这里只用Intent.FLAG_ACTIVITY_SINGLE_TOP举个例子,
如果设置了该FLAG,当该Activity处于栈顶的时候不会重新启动.且无法接受到新的Intent,这时候我们就需要onNewIntent()方法:
这是针对在其包中将launchMode设置为“singleTop”的活动或者在调用startActivity(Intent)时客户端使用FLAG_ACTIVITY_SINGLE_TOP标志的情况下调用的。 无论哪种情况,当活动在活动堆栈顶部重新启动时,而不是启动活动的新实例时,将使用用于重新启动的Intent在现有实例上调用onNewIntent() 它。
在接收新的意图之前,活动总是会暂停,因此您可以依靠在此方法之后调用onResume()。
请注意getIntent()仍然返回原始的Intent。 你可以使用setIntent(Intent)将它更新到这个新的Intent。
所以我们给intent添加一行代码如下:
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("data",number);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
并且在SecondActivity中添加onNewIntent()方法:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d(TAG, "onNewIntent: ");
if(intent != null){
setIntent(intent);
}
}
运行之后发现,无论点击多少个Notification都只有一个SecondActivity,且会更新Intent传递的number的值。