标签:guide notifications 下载进度条 android学习记录
notification,通知,显示在状态栏那里的信息。它看起来是这样的:
如果想设计更为人性化的notification,可参考android官方的design文档————notification
类似于AlertDialog的创建,notification的创建同样也是通过NotificationCompat.Builder来设置ui界面然后调用Builder.build()方法创建。当你想展示你的notification时,通过调用NotificationManager.notify()来把你的notification对象传给系统。
a.小图标。通过setSmallIcon()设置
b.标题。通过setContentTitle()设置
c.内容。通过setContentText()设置
都定义在了NotificationCompat.Builder中,可查看Builder类查看相关内容。
虽然理论上来说可以不定义action,但一般一个notification至少要有一个Action(一般来说是打开对应的activity),来跳转到对应页面进行相应的操作。嘿嘿,我们也可以添加button到notification中添加一些额外的操作(android4.1引进),当用户点击时实现相应操作。如果添加了action button,那么也应该在activity中也实现button对应的功能。(为了兼容)
怎么定义action?就是给notification对应的部分设置PendingIntent,PendingIntent可打开activity等组件。要设置action,则需调用相应的方法设置PendingIntent。
如实现用户点击contenttext时跳转activity则调用setContentIntent()方法。
作用:设置不同的重要程度,对应不同的提醒的方式。如设置为最重要的时候会弹出页面等。通过Builder.setPrioriy方法设置。
如何合适设置priority,请查看guide文档。
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 可以让你回到主屏幕。下面的一个部分会详细说说。
上面方法调用后,效果是这样的:
。。。有什么用?为毛我弄了没效果?
并不是所有的android版本都能实现你所定义的notification的功能(如4.1前不能添加action button),为此,我们需要在activity中提供对应的acitonbutton的功能,已满足低版本的需求。
为追求最好的兼容性,推荐使用NotificationCompat.Builder类构建notification。此外,推荐依据以下的模式实现notification:
1.把所有的功能在所启动的activity内先实现。(如音乐暂停,下一首等)。
2.确保所有的user都能通过点击notification进入对应的activity中。所以创建PendingIntent与对应部分绑定。
3.添加一些功能在notification中。如点击某button暂停播放音乐
有时候,你会发布多个同类型的notification,但要避免每一个创建一个notification。你可能会想要更新它,或添加一个新的。(如qq邮箱,当有多封接收的邮件时,它会更新,把所有的未读邮件放到一个inbox里,这样就只是用了一个notification。)
注意,inbox引进自android4.1
how?你在前面NotificationManager.notify()时有一个id,系统通过辨认Notification的id和对应id的Notification是否已移除来决定是更新一个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为指定的notification的id。
4.调用了NotificationManager.cancelAll()方法。
当你通过一个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.设置普通的Activity的PendingIntent
步骤:
1.在Manifest文件中定义应用程序的Activity间层级关系:
a.为支持4.1版本前,需要通过定义name为android.support.PARRENT_ACTIVITY的meta-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);这样就可以了。
引进自android 5.0.当对应级别的notification出现,而且手机处于活动状态(亮屏+解锁)时出现。
------学习自google官方guide文档-----Notifications
android学习记录(十七)---Notification 精要解析
标签:guide notifications 下载进度条 android学习记录
原文地址:http://blog.csdn.net/zuolovefu/article/details/45462963