android学习记录(十七)---Notification 精要解析

notification,通知,显示在状态栏那里的信息。它看起来是这样的:




如果想设计更为人性化的notification,可参考android官方的design文档————notification


  • 创建notification

 

类似于AlertDialog的创建,notification的创建同样也是通过NotificationCompat.Builder来设置ui界面然后调用Builder.build()方法创建。当你想展示你的notification时,通过调用NotificationManager.notify()来把你的notification对象传给系统。

 

  • notification必须要有的内容

 

a.小图标。通过setSmallIcon()设置

b.标题。通过setContentTitle()设置

c.内容。通过setContentText()设置



  • 其他可选的内容

 

都定义在了NotificationCompat.Builder中,可查看Builder类查看相关内容。

  • notificationaction

 

虽然理论上来说可以不定义action,但一般一个notification至少要有一个Action(一般来说是打开对应的activity),来跳转到对应页面进行相应的操作。嘿嘿,我们也可以添加buttonnotification中添加一些额外的操作(android4.1引进),当用户点击时实现相应操作。如果添加了action button,那么也应该在activity中也实现button对应的功能。(为了兼容)

 

怎么定义action?就是给notification对应的部分设置PendingIntentPendingIntent可打开activity等组件。要设置action,则需调用相应的方法设置PendingIntent

如实现用户点击contenttext时跳转activity则调用setContentIntent()方法。

 

  • Notification 优先权

 

作用:设置不同的重要程度,对应不同的提醒的方式。如设置为最重要的时候会弹出页面等。通过Builder.setPrioriy方法设置。

如何合适设置priority,请查看guide文档

 

  • 创建一个简单的notification
例:

	private void sendNotifiction() {
	        NotificationCompat.Builder builder = new Builder(getActivity());
	        builder.setContentTitle("NotifictionDemo").setContentText("i am 多啦a梦?").setSmallIcon(R.drawable.littlicon);
	        
	        Intent intent = new Intent(getActivity(),ResultActivity.class);
	        
	        TaskStackBuilder stackBuilder = TaskStackBuilder.create(getActivity());
	        stackBuilder.addParentStack(ResultActivity.class);
	        stackBuilder.addNextIntent(intent);
	        
	        PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
	        
	        builder.setContentIntent(pendingIntent);
	        
	        NotificationManager mNotificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
	        mNotificationManager.notify(mId, builder.build());
	        }


上面的TaskStackBuilder是为了让用户跳转到对应的activity后,如果点击backButton 可以让你回到主屏幕。下面的一个部分会详细说说。

 

上面方法调用后,效果是这样的:




  • notification一个拓展的布局

 

。。。有什么用?为毛我弄了没效果?

 

    • 兼容性处理

     

    并不是所有的android版本都能实现你所定义的notification的功能(如4.1前不能添加action button),为此,我们需要在activity中提供对应的acitonbutton的功能,已满足低版本的需求。

     

    为追求最好的兼容性,推荐使用NotificationCompat.Builder类构建notification。此外,推荐依据以下的模式实现notification

     

    1.把所有的功能在所启动的activity内先实现。(如音乐暂停,下一首等)。

    2.确保所有的user都能通过点击notification进入对应的activity中。所以创建PendingIntent与对应部分绑定。

    3.添加一些功能在notification中。如点击某button暂停播放音乐

     

    • Notification管理

     

    有时候,你会发布多个同类型的notification,但要避免每一个创建一个notification。你可能会想要更新它,或添加一个新的。(如qq邮箱,当有多封接收的邮件时,它会更新,把所有的未读邮件放到一个inbox里,这样就只是用了一个notification。)

     

    注意,inbox引进自android4.1

     

    1. Notification更新

     

    how?你在前面NotificationManager.notify()时有一个id,系统通过辨认Notificationid和对应idNotification是否已移除来决定是更新一个Notification还是添加一个Notification

    例:

    	final int notifictionId = 321;
    	        int currentNoti = 0;
    	        private void sendUpdateNotifiction() {
    	                NotificationCompat.Builder builder = new Builder(getActivity());
    	                builder.setContentTitle("NotifictionDemo").setContentText("多啦a梦"+currentNoti++).setSmallIcon(R.drawable.littlicon);
    	                
    	                Intent intent = new Intent(getActivity(),ResultActivity.class);
    	                
    	                TaskStackBuilder stackBuilder = TaskStackBuilder.create(getActivity());
    	                stackBuilder.addParentStack(ResultActivity.class);
    	                stackBuilder.addNextIntent(intent);
    	                
    	                PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    	                
    	                builder.setContentIntent(pendingIntent);
    	                
    	                NotificationManager mNotificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    	                mNotificationManager.notify(notifictionId, builder.build());
    	        }
    


    方法调用效果:




    如果不是采用更新的方式(即不同的id),则如图:




    2.Notifications移除

     

    以下4中事件发生的时候,notification会消失:

     

    1.notification下拉中,用户点击《清除所有》button

    2.用户点击了你的notification,同时在创建notification使设置了setAutoCancel 方法为true。如果你并为调用Builder.setAutoCancel方法为true,则用户点击了该notification后,该notification依然存在。

    3.调用了NotificationManager.cancel()方法,参数id为指定的notificationid

    4.调用了NotificationManager.cancelAll()方法。

     

    • 实现通过notification所打开的Activity的导航

     

    当你通过一个notification打开对应activity时,应该提供一个activity的导航功能:当在该activity点击back button时返回桌面;查看最近打开的应用程序列表时能看到该activity。为此,你需要在一个新的栈中启动这个activity。如何使用PendingIntent去提供一个新的Activity栈基于你如何启动这个Activity。通常来说有两种情况:

     

    1.普通的Activity

    就是通过普通方式打开应用程序同样也可以看到的Activity。对于这种情况,我们利用PendingIntent建立一个新的栈,并实现一种如同从普通方式打开应用程序时的导航模式。并且它不在乎你是否正在使用该程序,通过Notification打开的Activity都不会变。

     

    如:我已打开:邮箱》写邮件。此时收到了新的邮件,并点击该Notification进入阅读该邮件,那么我一直按back的导航的顺序是这样的:邮件详细》邮件列表》邮件主页》home

     

    2.特殊的Activity

    即只能通过Notification查看的Activity。通过普通方式进入应用程序里面看不到该Activity。在这种情况下,让PendingIntent开启一个新的栈,因为这个Activity与应用程序里的Activity并没什么关系,所以让它点击后直接返回home

     

    1.设置普通的ActivityPendingIntent

     

    步骤:

     

    1.Manifest文件中定义应用程序的Activity间层级关系:

    a.为支持4.1版本前,需要通过定义nameandroid.support.PARRENT_ACTIVITYmeta-data

    b.为支持4.1及后版本,activity标签中定义元素android:parentActivityName的值。

     

    For Example

    		 <activity
    		            android:name="com.example.notificationdemo.MainActivity"
    		            android:label="@string/app_name" >
    		            <intent-filter>
    		                <action android:name="android.intent.action.MAIN" />
    		
    		                <category android:name="android.intent.category.LAUNCHER" />
    		            </intent-filter>
    		        </activity>
    		        <activity
    		            android:name="com.example.notificationdemo.ResultActivity"
    		            android:parentActivityName="com.example.notificationdemo.MainActivity" >
    		            <meta-data
    		                android:name="android.support.PARENT_ACTIVITY"
    		                android:value="com.example.notificationdemo.MainActivity" />
    		        </activity>
    


    2. 基于启动 Activity Intent 来创建一个回退栈。
     
    a . 创建启动 Activity Inent
    b . 通过调用 TaskStackBuilder.creat() 来创建一个 Stack Builder 实例
    c . 通过调用 addParentStack () 把回退栈添加到 StackBuilder 实例中 , 根据你在 Manifest 文件中定义的 Activity 的父子关系,该操作会把所有启动父 Activity Intent 都放入到栈中。但还没添加启动该 Activity Inent
    d . 通过调用 addNextInent 方法把启动该 Activity Intent 放入栈中。
    e . 当你需要给 Intent 添加参数时,你可直接添加 extra Intent 中,或通过 TaskStackBuilder.editIntentAt ) 方法获得指定位置的 Intent 然后放入 extra 。这在有些时候是比较有用的。

    f.通过调用Builder.getPendingIntent()方法获取PendingIntent。然后使用该PendingIntent


    Example

    		NotificationCompat.Builder builder = new Builder(getActivity());
    		builder.setContentTitle("NotifictionDemo").setContentText("i am 多啦a梦?").setSmallIcon(R.drawable.littlicon);
    		
    		Intent intent = new Intent(getActivity(),ResultActivity.class);
    		
    		TaskStackBuilder stackBuilder = TaskStackBuilder.create(getActivity());
    		stackBuilder.addParentStack(getActivity());
    		stackBuilder.addNextIntent(intent);
    		PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    		
    		builder.setContentIntent(pendingIntent);
    		
    		NotificationManager mNotificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    		mNotificationManager.notify(mId, builder.build());
    

     

    2. 特殊的 Activity
     
    由于它并没和其他 Activity 有联系,所以,在一个全新的,没有其他 Activity 的栈中打开它。同时,也不需要再最近任务看到该 Activity
     
    步骤:
     
    1. Manifest 文件中定义 activity 及其属性。
     
    android:taskAffinity=""
    作用:设置该 Activity 没有与之有联系的 activity 。与 Intent FLAG_ACTIVITY_NEW_STACK 一起使用,确保 activity 在一个新的栈启动,且不影响 Application 的其他 Activity 。(详情请看 Tasks and Back Stack 文档)
     
    android:excludeFromRecents="true"
    作用:使该 Activity 不出现在最近任务中。
     
    Example

    		<activity 
    		            android:name="com.example.notificationdemo.AloneActivity"
    		            android:taskAffinity=""
    		            android:excludeFromRecents="true"
    		            android:launchMode="singleTask"
    		            ></activity>
    


    2. 构建并发布 Notification
     
    a . 创建 Intent
    b . 设置在新的 Task 中打开 Activity 。设置 Intent Flag FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK
    c . 设置 Intent 的其他选项
    d . 构建 PendingIntent
     
    Example :

    		NotificationCompat.Builder builder = new Builder(getActivity());
    		        builder.setContentTitle("NotifictionDemo")
    		                .setContentText("i am 多啦a梦?")
    		                .setSmallIcon(R.drawable.littlicon);
    		
    		        Intent intent = new Intent(getActivity(), AloneActivity.class);
    		        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
    		                | Intent.FLAG_ACTIVITY_NEW_TASK);
    		        PendingIntent pendingIntent = PendingIntent
    		                .getActivity(getActivity(), 0, intent,
    		                        PendingIntent.FLAG_UPDATE_CURRENT);
    		
    		        builder.setContentIntent(pendingIntent);
    		
    		        NotificationManager mNotificationManager = (NotificationManager) getActivity()
    		                .getSystemService(Context.NOTIFICATION_SERVICE);
    		        mNotificationManager.notify(mId, builder.build());
    

    • Notification中显示进度条

     
    我们应该也都看过下载时在 Notification 显示的下载的进度条,看完这部分,你也可以做到。
     
    我们可通过调用 NotificationCompat.Builder .setProgress () 方法把 progress bar 添加到你的 Notification 中,然后发布该 Notification 即可。实现原理为:更新带有新的进度的 Notification 。即可实现该效果。
     
    注: android4.0 以上通过 setProgress 方法实现进度条显示,而 4.0 前的版本需要实现自己的 Notification layout 才可以。
     
    同时,进度条也分为两种形式。
    1. 知道当前的进度(如下载)

    2.不知道当前进度(如安装应用程序)。


      1. 显示知道进度的 progress bar
     
    方法:调用 setProgress 方法设置最大进度,当前进度,然后发布 Notification
     
    当进度完成后,你可以移除 progress bar ,也可保留。但一般来说,当进度完成时,都需要去更新 Notification 的内容。如设置 title 为下载完成。移除 progress 的方法为: setProgress(0,0,false)
     

    Example:

    	private void sendFixProgressNotifiction() {
    	
    	        final NotificationCompat.Builder builder = new NotificationCompat.Builder(
    	                getActivity());
    	        builder.setContentTitle("正在下载").setContentText("下载进度")
    	                .setSmallIcon(R.drawable.littlicon);
    	
    	        final NotificationManager notificationManager = (NotificationManager) getActivity()
    	                .getSystemService(Context.NOTIFICATION_SERVICE);
    	
    	        new Thread(new Runnable() {
    	
    	        @Override
    	        public void run() {
    	                int progress = 0;
    	                for (; progress <= 100; progress += 10) {
    	                        builder.setProgress(100, progress, false);
    	                        notificationManager.notify(321, builder.build());
    	
    	        try {
    	                Thread.sleep(2000);
    	        } catch (InterruptedException e) {
    	                e.printStackTrace();
    	        }
    	        }
    	
    	        builder.setContentText("下载完成");
    	        builder.setProgress(0, 0, false);
    	        notificationManager.notify(321, builder.build());
    	
    	        }
    	        }).start();
    	        }
    


    调用效果如图:




    2. 不知道进度的 progress bar
     
    仅仅是 progress bar 的一些 ui 的差别而已。该 progress bar 就是一个动画,它持续运动,直到我们移除该动画。
     
    与前面 progress bar 的不同之处:

    调用方法Builder.setProgress(0,0,true)而不是Builder.setProgress(max,progress,false);当第三个参数设置为true时会忽略前两个参数,因为根本不需要知道它们的值。


     只需修改上面的例子中的

    builder.setProgress(100, progress, false);
    
    为:

    builder.setProgress(0, 0, true);
    
    这样就可以了。

    • Heads-up Notification
     

    引进自android 5.0.当对应级别的notification出现,而且手机处于活动状态(亮屏+解锁)时出现。


    有两种情况可出现这样的 Notification :、
     
    1. 用户正处于一个全屏模式
    2.Notification Priority 级别 而且有铃声 和震动(不管是否全屏都可以)



    ------学习自google官方guide文档-----Notifications



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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值