• Android解决Intent中的数据重复问题


    转载地址:http://www.cnblogs.com/anrainie/articles/2383941.html

    最近在研究Android,遇到了一些Notification(通知)的问题:
    
    1、Notification如何传递参数
    
    2、Notification如何区别化
    
    3、从Intent(意图)寻找Activity(活动)说起,Android的Activity栈。
    
    ===============================================================
    
    先从发送通知开始。
    
    首先,在发送一个Notification前,我们需要准备好一个NotificationManager
    
    获得途径:
    
    NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    
    this为Application或者Activity。
    
    然后,定义好我们的Notification:
    
    1、定义一个Notification具备的三个基本参数icon,title,以及when
    
    ?
    int icon=R.drawable.teller_call_1;
     
    long when = System.currentTimeMillis();
     
    Notification notification = new Notification(icon, null, when);
      
    
    这个定义比较随意。
    
    2、为notification添加打开关闭方式:
    
    
    //点击notification之后,该notification自动消失
    
    notification.flags = Notification.FLAG_AUTO_CANCEL;
    
    //notification被notify的时候,触发默认声音和默认震动
    
    notification.defaults=notification.DEFAULT_SOUND|notification.DEFAULT_VIBRATE;
    
    
    
    
    3、为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);
    
    
    
    
    4、发送通知
    
    //notifacation_id由自己指定,为每一个Notification对应的唯一标志
    
    mNotificationManager.notify(notifacation_id, notification);
    
    
    
     
    
    ======================================================
    
    看到这里,我们明白了,我们可以为Notification指定它的图标,标题,时间,提醒方式,点击之后的动作。
    
    延展想一下,我们还能做什么呢?
    
    1、由于每个Notification的ID是唯一的,所以我们可以删除某些通知:
    
    mNotificationManager.cancel(notifacation_id);
    
    
    
    2、同理,通过重复发送相同ID的Notification,我们还可以更新某些通知:
    
    mNotificationManager.notify(notifaction_id,newNotification);
    
    
    
    3、由于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还有什么设置:
    
    1、PendingIntent.FLAG_UPDATE_CURRENT
    
    Extra会被更新为最后一个传入的Intent的Extra
    
    2、PendingIntent.FLAG_ONE_SHOT
    
    send()只能被执行一次,即是说,假如该通知点击后不消失,那么再次点击不会发生任何事。
    
    3、PendingIntent.FLAG_NO_CREATE
    
    这个最好别用,不创建。
    
    4、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依旧存在
    
    方法有二:
    
    1、在Activity的onPause()方法体中增加:
    
    finish();
    
    这样,在打开新的Activity的时候,旧的就进入了暂停态,启动onPause(),然后执行finish(),活动结束
    
    好吧,这是个蠢办法,请不要使用
    
    2、设置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);
    
    之后,这个意图一旦产生,就会自动清除栈顶的活动,即是说,上一个被打开的活动会被终结掉,于是就实现了没有两个相同的活动被同时打开。
  • 相关阅读:
    PE文件简介
    hook键盘驱动中的分发函数实现键盘输入数据的拦截
    遍历系统中加载的驱动程序以及通过设备对象指针获取设备对象名称
    如何利用git shell提交代码到github
    驱动开发中的常用操作
    3.1_栈_顺序存储结构(数组形式)
    2.6_链表深入
    2.5_线性表的链式存储结构_双向链表
    2.4_线性表的链式存储结构_单链表具体实现
    2.3_线性表的链式存储结构_单链表
  • 原文地址:https://www.cnblogs.com/tony-yang-flutter/p/notification_data.html
Copyright © 2020-2023  润新知