码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2015-05-04 10:07:58      阅读:403      评论:0      收藏:0      [点我收藏+]

标签:guide   notifications   下载进度条   android学习记录   

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.基于启动ActivityIntent来创建一个回退栈。
 
a.创建启动ActivityInent
b.通过调用TaskStackBuilder.creat()来创建一个Stack Builder实例
c.通过调用addParentStack()把回退栈添加到StackBuilder实例中,根据你在Manifest文件中定义的Activity的父子关系,该操作会把所有启动父ActivityIntent都放入到栈中。但还没添加启动该ActivityInent
d.通过调用addNextInent方法把启动该ActivityIntent放入栈中。
e.当你需要给Intent添加参数时,你可直接添加extraIntent中,或通过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。与IntentFLAG_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。设置IntentFlagFLAG_ACTIVITY_NEW_TASKFLAG_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



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

标签:guide   notifications   下载进度条   android学习记录   

原文地址:http://blog.csdn.net/zuolovefu/article/details/45462963

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!