最近在研究Android,遇到了一些Notification(通知)的问题: html
一、Notification如何传递参数 this
二、Notification如何区别化 spa
三、从Intent(意图)寻找Activity(活动)提及,Android的Activity栈。 code
=============================================================== htm
先从发送通知开始。 对象
首先,在发送一个Notification前,咱们须要准备好一个NotificationManager blog
得到途径: 事件
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); ci
this为Application或者Activity。 get
而后,定义好咱们的Notification:
一、定义一个Notification具有的三个基本参数icon,title,以及when
int icon=R.drawable.teller_call_1;
long when = System.currentTimeMillis();
Notification notification =new Notification(icon,null, when);
|
这个定义比较随意。
二、为notification添加打开关闭方式:
//点击notification以后,该notification自动消失 notification.flags = Notification.FLAG_AUTO_CANCEL; //notification被notify的时候,触发默认声音和默认震动 notification.defaults=notification.DEFAULT_SOUND|notification.DEFAULT_VIBRATE;
三、为notification添加一个意图(Intent):
//该意图用来打开NotificationList这个新的Activity Intent openintent= new Intent(this, NotificationList.class); //包装该Intent,只有包装后的Intent才能被Notification所用,这是由于Notification须要指定一些额外的参数 PendingIntent contentIntent = PendingIntent.getActivity(tradeRoom .getApplicationContext(), 0, openintent, 0); notification.setLatestEventInfo(tradeRoom.getApplicationContext(), title, info, contentIntent);
四、发送通知
//notifacation_id由本身指定,为每个Notification对应的惟一标志 mNotificationManager.notify(notifacation_id, notification);
======================================================
看到这里,咱们明白了,咱们能够为Notification指定它的图标,标题,时间,提醒方式,点击以后的动做。
延展想一下,咱们还能作什么呢?
一、因为每一个Notification的ID是惟一的,因此咱们能够删除某些通知:
mNotificationManager.cancel(notifacation_id);
二、同理,经过重复发送相同ID的Notification,咱们还能够更新某些通知:
mNotificationManager.notify(notifaction_id,newNotification);
三、因为Notification的包装内容为Intent,咱们就能够方便地为通知被点击的触发的事件传值:
Intent openintent= new Intent(this, NotificationList.class); openintent.putExtra("isRead", true); openintent.putExtra("name", "CaiYu");
等等,真的能够传值么?
答案是能够,可是,这样传值就完蛋了。
如今回到下面的位置来:
PendingIntent contentIntent = PendingIntent.getActivity(tradeRoom .getApplicationContext(), 0, openintent, 0);
注意最后一个“0”,0表示什么?表示什么都不作,而后下次你传进来的Intent,若是被发现是同一个Intent,则全部通知都保持为同一个Intent。好吧,事实上,Intent并非同一个,只是Extra被保留了。
嗯,你应该会指望每一个Notification都能干点不同的事情,按上面的方式这样来,每一个具有相同Intent的Notification相互之间,实际上是毫无区别的。
好,咱们来看下除了0之外Android还有什么设置:
一、PendingIntent.FLAG_UPDATE_CURRENT
Extra会被更新为最后一个传入的Intent的Extra
二、PendingIntent.FLAG_ONE_SHOT
send()只能被执行一次,便是说,假如该通知点击后不消失,那么再次点击不会发生任何事。
三、PendingIntent.FLAG_NO_CREATE
这个最好别用,不建立。
四、PendingIntent.FLAG_CANCEL_CURRENT
这个,会更新Extra,但仍是全部的Intent都保持同一个Extra。
嗯,明显都不是你想要的。
其实答案根本不在PendingIntent包装上。
PendingIntent所作的所有事情都只是对一样的Intent进行处理,关键词,在于“一样的”
既然每次你打开的都一个Intent,那区分PendingIntent就没有意义了
因此,在Intent定义的时候,你还须要区分Intent
推荐方式:
openintent.setData(Uri.parse("custom://"+System.currentTimeMillis()));
这样就实现了Intent的区别化,之后每次传入的Intent都会具有不一样的Extra,固然,PendingIntent须要定义为PendingIntent.FLAG_UPDATE_CURRENT
到这个地方,其实还剩下一个问题,很快你就会发现
每次点击通知,都正确的弹出你要的Activity,可是以前的打开的Activity依旧存在
方法有二:
一、在Activity的onPause()方法体中增长:
finish();
这样,在打开新的Activity的时候,旧的就进入了暂停态,启动onPause(),而后执行finish(),活动结束
好吧,这是个蠢办法,请不要使用
二、设置Intent:
openintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
是的,这句就够了,这里我得说一下Activity的栈机制:
咱们先来看看Intent的结构new Intent(context(),Notification.class);
第一个参数为产生该意图(Intent)的活动,这个逻辑再清晰不过了,要作的事情得有个发出的主体
第二个参数为该意图的对象,便是这个意图是什么,咱们来看看。
呃!??这里没有对象……
是的,咱们只有了一个对象的类名,但远远不是某个具体的对象,这是反射么?反射能经过一个类名来找到某个特定的类实例么?
实现以下:
Android有一个栈机制,每一个产生的活动在过了产生期后,都会进入这个栈,新的活动压着旧的活动,每一次寻找类名的时候,都默认提取的是栈顶的活动。这也是为何Android能快捷的执行返回操做。
回到原点来,咱们为Intent添加:
openintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
以后,这个意图一旦产生,就会自动清除栈顶的活动,便是说,上一个被打开的活动会被终结掉,因而就实现了没有两个相同的活动被同时打开。