您的位置:首页 > 移动开发 > Android开发

android开发之Notification(一)

2016-09-17 14:30 417 查看
                “我没有很聪明,也不是那么努力,我只是有点不服输”

0x01.简介

        A notification is a message you can display to the user outside of your application's normal UI. When you tell the system to issue a notification, it first appears as an icon in the notification area. To see the details of the notification, the user
opens the notification drawer. Both the notification area and the notification drawer are system controlled areas that the user can view at any time. 

--引用谷歌关于Notification的描述
        Notification是一个将你程序的消息展示在程序之外的UI控件,当你告诉系统去产生一个Notification时,它会在Notification area出现一个图标,你可以打开Notification drawer去看详细的信息。Notification are 和Notification drawer都是系统控制的区域,用户可以随时看到。

        Notification不仅仅用于显示一则消息,也可以用于和用户进行交互。比如音乐播放,它的Notification具有音乐控制功能,并且在android7.0(api level 24)上Notification可以直接通过Notification进行回复,比如有一则微信消息,你可以通过下拉框直接回复啦,不用通过点进去再回复了,我想在Android7.0系统上,微信和QQ应该会这么做。效果图如图1.0(引用谷歌官网)。



图1.0

0X02.最简单的Notification

        在Android2.0之前谷歌提供的是Notification类去构建一个Notification通知,而在之后supportV4包中引入了NotificationCompat来代替Notification类来构建,其中的原因我也不明白。即使谷歌在android3.0的时候在Notification类中加上Notification.Build类用于构造Notification,也不能逃脱Notification被淘汰的命运,这篇博客整篇都是用NotificationCompat来构造。值得一提,对于NotificationCompat.Build(this)这是采用设计模式中的构造模式。
        谷歌说如果你想构造一个Notification你会用到Notification.Build类中很多方法,但是你必须要用到以下3个方法:

setContentTitle() 设置Notification标题
setContentText() 设置Notification内容
setSmallIcon() 设置Notification小图标(对,还有setLargeIcon不同图片用于不同的设备)

谷歌说一定要有这3个方法其实是不对的,因为如果你使用自定义布局的Notification就不会涉及到这3个。但是毋庸置疑大部分都还是需要设置这3个属性的。Notification当然除了这些属性还有别可选属性,但是谷歌还是建议你在可选属性上至少选一个,不然用户点了你的Notification什么反应都没有会让人觉得很傻。
做一个最简单的例子,构建一个Notification显示出来。

NotificationCompat.Builder build = new NotificationCompat.Builder(this);//定义一个创建Notification的build
build.setContentTitle("this is title").setContentText("this is text").setSmallIcon(R.mipmap.ic_launcher);//为Notification设置所需要的属性
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//获取系统Notification服务
manager.notify(0, build.build());//显示


        上面这个代码是用来显示一个Notification,并且点击通知后会进入SpecialNotificationActivity这个Activity中。然后按退出呢,就退回原来的界面了。上面是一个最简单的例子设置一个Notification。仅仅设置了必须的3个属性。它只能用来通知一则消息。方法notify(int id, Notification notification),是通知系统加载这个Notificantion,一个应用程序中id不同,Notification就会不同。我们就可以通过id更新不同的Notification了。

0X03.结合PendingIntent的Notification

        有的时候我们的需要为我们的Notification增加点击事件。比如说一则邮件通知,当用户点击的时候,需要提供一个更为详细的页面用于展示具体的内容,那就需要在系统中启动我们特定的Activity。我们一般都是用Intent从我们App的一个Activity跳到另外一个Activity,从外部启动我们的的Activity,SDK提供了一个类是PendingIntent,有了这个我们就可以从系统启动我们的组件了(如果大家需要详细介绍,大家可以留言,我会把这个类的学习mark一下)。 
      
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//创建build对象
builder.setContentTitle("this is title").setContentText("this is text").setSmallIcon(R.mipmap.ic_launcher);//设置必须的属性
Intent notifyIntent =  new Intent(this, SpecialNotificationActivity.class);//创建用于跳转的Intent
PendingIntent notifyPendingIntent = PendingIntent.getActivity(  this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);//获得可以在别的应用可以用的Intent,别名PendingIntent。
builder.setContentIntent(notifyPendingIntent);//设置外部应用需要用的PendingIntent
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);//获取系统的Notification服务
mNotificationManager.notify(0, builder.build());//显示这个Notification
        PendingIntent是在Intent的上面进行进一步的封装,getActivity(Context context, int requestCode, Intent intent, int flag)可以获得一个PendingIntent。我们看下具体的参数



context,intent就不说了,requestCode是和flag配套使用的,requestCode是用来标记PendingIntent是否相同,当flags设成FLAG_UPDATE_CURRENT时,并且赋给一个Notification,它会更新所有和它有相同的requestCode的PendingIntent内容(一个APP情况下),即使Notification拥有不用的ID。比如下面段代码
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);//获取系统的Notification服务
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("this is title1").setContentText("this is special").setSmallIcon(R.mipmap.ic_launcher);//设置必须的属性
Intent intent1 = new Intent(this, Activity1.class);
PendingIntent pendingIntent2 = PendingIntent.getActivity(this, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentIntent(pendingIntent2);
notificationManager.notify(1, builder.build());
<span style="white-space:pre">	</span>//下面我们增加一个Notification,ID不相同,但是生成的PendingIntent的requestCode,并且把Flag设成FLAG_UPDATE_CURRENT.
Intent intent2 = new Intent(this, Activity2.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentTitle("this is title 2");//显示不同的标题
builder.setContentIntent(pendingIntent);
notificationManager.notify(2, builder.build());//ID不同就会显示两个Notification
        一开始我们为title1设置的是跳转到Activity1,为title2设置的是跳转到Activity2。但是实际结果是点击两个都会跳转到Activity2,这就是requestCode和flag共同下的作用,当第二个PendingIntent传入Notification时,flag设置成FLAG_UPDATE_CURRENT,会更新所有requestCode和它相同的PendingIntent,所以Title1中的也被更新了。有位很详细的介绍了PendingIntent的requestCode参数戳这查看

0X04.自定义的Notification

        当然可能自定义布局满足不了我们,我们可以为Notification设定自己的布局。
NotificationCompat.Builder build = new NotificationCompat.Builder(this);//定义一个创建Notification的build
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, Main2Activity.class), PendingIntent.FLAG_UPDATE_CURRENT);//获得PendingIntent
RemoteViews rm = new RemoteViews(getPackageName(), R.layout.notification_custom);//生成RemoteView
rm.setOnClickPendingIntent(R.id.press_here_button, pi);//为其中一个按钮设置点击事件
build.setContent(rm);//设置RemoteVIew
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//获取系统Notification服务
manager.notify(0, build.build());//通知显示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this is custom layout"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this is second line"/>
<Button
android:id="@+id/press_here_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="press here"/>
</LinearLayout>
        
        我们用RemoteViews(String packageName, int layoutId)实例化一个RemoteViews,第一个参数是你App安装之后的地址,第二个是你布局文件的我id
        我们通过setContent(RemoteView)这个方法设置自定义布局,这个时候setContentTitle等方法不会起作用了。setContent接受一个RemoteView这个类从名字也可以看出来,这是用来描述视图可以用来在别的进程中展示。值得一提PendingIntent和RemoteView都继承了Parcelable。
设置监听setOnClickPendingIntent(int, PendingIntent)。我们可以启动一些app的组件。

0X04.Notification的其它功能简介

        当然Notification还有很多其他的功能,不总结了,可以通过戳这到官网的介绍
        Builder.setPriority(int),这是一个设置Notification优先级的方法,值是从-2到2,没有设置默认是0,没有明确说明不同等级会有什么区别,我么自己应该明白当我们通知越紧急就把优先级设的越高。
        Builder.setStyle(NotificationCompat.Style),这个方法可以用来显示更多的信息,不仅仅只是设置text的内容

        Builder.setAutoCancel(),创建的时候设置这个,用户点击的时候回自动取消
        Builder.setProgress(max, progress, false),可以用来边设置一个进度条的Notification
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: