构造PendingIntent时第四个参数flags的设置以及在Notification中的不同作用

PendingIntent的位标识符:

FLAG_ONE_SHOT   表示返回的PendingIntent仅能执行一次,执行完后自动取消

FLAG_NO_CREATE     表示如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL

FLAG_CANCEL_CURRENT      表示相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景

FLAG_UPDATE_CURRENT     表示更新的PendingIntent

PendingIntent第四个参数为int类型的flags,首先看一下官方文档对它的描述:

flags May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.
可见flags可以有四个取值,分别是FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT。这四种取值每一种都有特定的意义。当然,也可以不使用上述四种常量中的任意一种,即不为PendingIntent指定flags,此时只需要传入一个数字0即可

例如:
PendingIntent.getActivity(context, requestCode, someIntent, 0);
传入0(第四个参数),就意味着你不打算使用任何一种flag来控制PendingIntent的创建。

接下来看一下四种flags的各自功能:

FLAG_CANCEL_CURRENT:如果要创建的PendingIntent已经存在了,那么在创建新的PendingIntent之前,原先已经存在的PendingIntent中的intent将不能使用

FLAG_NO_CREATE:如果要创建的PendingIntent尚未存在,则不创建新的PendingIntent,直接返回null

FLAG_ONE_SHOT:相同的PendingIntent只能使用一次,且遇到相同的PendingIntent时不会去更新PendingIntent中封装的Intent的extra部分的内容

FLAG_UPDATE_CURRENT:如果要创建的PendingIntent已经存在了,那么在保留原先PendingIntent的同时,将原先PendingIntent封装的Intent中的extra部分替换为现在新创建的PendingIntent的intent中extra的内容

PendingIntent重写了equals方法,判定两个PendingIntent是否相同的依据是它封装的Intent是否“相同”和requestCode是否一致。注意,“相同”上打了引号,这是因为在比较PendingIntent中封装的intent时是否相同时,使用的是Intent的filterEquals方法,该方法认为只要两个intent具有相同的action、data、categories、components、type和flags(这个flags是intent的flags)就认为它们两个是“相同”的,filterEquals是不会比较两个intent的extra部分和内存地址的。另外需要注意的是,Intent并没有重写equals方法,所以如果使用Intent的equals方法比较两个intent对象的话,比较的是两个对象的内存地址。看有如下代码示例:

int requestCode = 1;

Intent intentA = new Intent( );

intentA.putExtra("name","AAA");

Intent intentB = new Intent( );

intentB.putExtra("name","BBB");
PendingIntent p1 = PendingIntent.getActivity(context, requestCode, intentA, 0);
PendingIntent p2 = PendingIntent.getActivity(context, requestCode, intentB, 0);

Log.d("TAG","两个intent是否相等(equals)"+intentA.equals(intentB));//false

Log.d("TAG","两个intent是否相等(filterEquals)"+intentA.filterEquals(intentB));//true

Log.d("TAG","两个PendingIntent是否相等"+p1.equals(p2));//true

有了上面的知识铺垫,接下来,用不同的flags创建Notification中使用的PendingIntent,看看不同的flags所产生的不同效果:

public void sendMsg(){
            int requestCode = 1;
            Intent intentA = new Intent(this, SecondActivity.class);
            intentA.putExtra("name","AAA");
            Intent intentB = new Intent(this, SecondActivity.class);
            intentB.putExtra("name","BBB");
            PendingIntent p1 = PendingIntent.getActivity(this, requestCode, intentA, PendingIntent.FLAG_NO_CREATE);
            PendingIntent p2 = PendingIntent.getActivity(this, requestCode, intentB, PendingIntent.FLAG_NO_CREATE);
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Notification notification = new Notification.Builder(this).
                    setContentTitle("title").
                    setContentText("Content Text").
                    setSmallIcon(R.mipmap.ic_launcher).
                    setAutoCancel(true).
                    setContentIntent(p1).
                    build();
            manager.notify(1, notification);
            Notification notification2 = new Notification.Builder(this).
                    setContentTitle("title2").
                    setContentText("Content Text2").
                    setSmallIcon(R.mipmap.ic_launcher).
                    setAutoCancel(true).
                    setContentIntent(p2).
                    build();
            manager.notify(2, notification2);
        }

SecondAcitivity中有一个TextView,用来显示打开SecondActivity的Intent中的String Extra内容:

TextView tv = (TextView) findViewById(R.id.test);
tv.setText(getIntent().getStringExtra("name"));

这里重点看创建PendingIntent时的第四个参数:

使用0时,意味着不使用flags进行创建PendingIntent时的控制,那么此时创建的两个PendingIntent对于安卓来说是一样的,并且不会去更新PendingIntent中封装的intent的extra内容。因此无论点击哪个通知都会跳转到SecondActivity的,并且都会在tv里面显示的是AAA。

现在改变一下创建PendingIntent时的flags:

设置两个PendingIntent的flags均为FLAG_CANCEL_CURRENT,此时随着p2的创建,p1里面的Intent内容会失效。因此,点击第一个Notification的时候,只会自动取消掉该通知(因为设置了AutoCancel为true)并且返回到MainActivity界面而不会发生跳转。当点击第二个Notification的时候,p2发挥作用,所以点击通知会进行跳转到SecondActivity,并在SecondActivity的tv中显示BBB。

设置两个PendingIntent的flags均为FLAG_NO_CREATE,此时无论点击哪个通知,都不会有任何效果,通知即不会自动消失也不会跳转到任何界面(即使MainActivity界面都无法跳转)。这是因为在之前没有“相同”的PendingIntent时,FLAG_NO_CREATE也根本不会创建新的PendingIntent而是直接返回null。这样在点击通知时,根本就没有PendingIntent,所以也不会跳转也不会取消通知。FLAG_CANCEL_CURRENT和FLAG_NO_CREATE最大的区别就是前者会保留PendingIntent,只是把里面的Intent取消掉。另外还可以知道很重要的一点,如果仅仅设置了通知的AutoCancel而没有设置PendingIntent的话,点击通知时,通知是不会消失的!

设置两个PendingIntent的flags均为FLAG_ONE_SHOT,相同的PendingIntent哪个先获得点击,哪个就会被执行。FLAG_ONE_SHOT不具备更新相同的PendingIntent中Intent的extra的能力。因此,如果先点击通知2,会跳转到SecondActivity,并在SecondActivity的tv中显示AAA,再点击通知1,仅仅会取消通知1并返回到MainActivity。如果先点击通知1,会跳转到SecondActivity,并在SecondActivity的tv中显示AAA,再点击通知2,仅仅会取消通知2并返回到MainActivity。

最后,设置两个PendingIntent的flags均为FLAG_UPDATE_CURRENT,使用该flags时,后创建的PendingIntent在遇到已经存在的相同的PendingIntent时,会去更新原先PendingIntent中封装的intent的extra内容为最新的PendingIntent封装的Intent中的extra内容。即,p2会把p1的intent的extra内容更新为自己的extra。此时,无论点击哪个通知,都会跳转到SecondActivity,并且在tv上显示最新一个PendingIntent中Intent中的extra内容,即都会显示BBB。

转载自https://blog.csdn.net/piglite/article/details/46581789


最后,关于通知使用更详细更全面的介绍,推荐阅读这个人的blog,写的非常全面和详细:

http://blog.csdn.net/vipzjyno1/article/details/25248021


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值