12.10 Notification" class="reference-link">12.10 Notification
Notification作为一个事件触发通知型的交互提示接口,让我们可以在获得消息的时候,在状态栏、锁屏界面得到相应的提示信息。从QQ、微信到各种推送通知、短信,这些Notification常常出现在状态栏。
Google在Android 5.0上又进一步改进了通知栏,优化了Notification。现在,在Android 5.X设备上,一个标准的Notification界面如图12.32所示。
图12.32 标准Notification界面
当长按Notification的时候,会显示消息来源,如图12.33所示。
图12.33长按Notification后显示消息来源
Notification会有一个从白色到灰色的动画切换效果,最终显示发出这个Notification的调用者。同时,在Android 5.X设备上,锁屏状态下我们也可以看见Notification通知了,如图12.34所示。
图12.34 锁屏状态下的Notification
下面我们就分四重境界来看看该如何在Android 5.0下使用Notification,整个示例程序的运行效果如图12.35所示。
图12.35 Notification示例程序界面
12.10.1 基本的Notification" class="reference-link">12.10.1 基本的Notification
通过Notification.Builder创建一个Notification的builder,代码如下所示。
- Notification.Builder builder = new Notification.Builder(this);
这个与AlertDialog的使用方法是不是非常相似呢?接下来,给点击Notification后要执行的操作增进一个Intent,由于这个Intent不是马上就执行的,而是由用户触发的,所以Android给这样的Intent提供了一个PendingIntent来帮助我们完成这样的延迟操作。
PendingIntent的使用非常简单,只需要在普通Intent的基础上包装一层就可以了,代码如下所示。
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));
- //构造PendingIntent
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
这样当点击Notification之后,就会触发PendingIntent事件,打开浏览器开始浏览网页。
与使用AlertDialog一样,有了builder对象,可以给它增加各种属性。
- builder.setSmallIcon(R.drawable.ic_launcher);
- builder.setContentIntent(pendingIntent);
- builder.setAutoCancel(true);
- builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_launcher));
- builder.setContentTitle("Basic Notifications");
- builder.setContentText("I am a basic notification");
- builder.setSubText("it is really basic");
这些属性的具体含义,大家也不必一个个去仔细理解,结合后面演示的效果和命名,很容易就能理解了。最后一步,自然是将Notification显示出来,Android系统通过NotificationManager系统服务来帮助我们管理Notification,并通过调用notify方法来发出Notification。
- //通过NotificationManager来发出Notification
- NotificationManager notificationManager =
- (NotificationManager) getSystemService(
- NOTIFICATION_SERVICE);
- notificationManager.notify(NOTIFICATION_ID_BASIC,
- builder.build());
调用NotificationManager的notify方法时,需要传进去一个ID。每个Notification都会有一个ID,这个ID就是用来区分不同的App的Notification的。
通过以上很简单的几步,就完成了一个基本的Notification。Notification还可以配置LED灯和震动等选项,不过这些都只是增加一个属性罢了,这里就不详细演示了。最后来看看Basic Notification的效果如何,效果如图12.36所示。
相信结合运行出来的例子,大家应该可以很清楚地理解上面配置的参数的意义了。
图12.36 Basic Notification显示效果
12.10.2 折叠式Notification" class="reference-link">12.10.2 折叠式Notification
折叠式Notification也是一种自定义视图的Notification,常常用于显示长文本。它拥有两个是视图状态,一个是普通状态下的视图状态,另一个是展开状态下的视图状态。在Notification中,使用RemoteViews来帮助我们创建一个自定义的Notification视图,代码如下所示。
- //通过RemoteViews来创建自定义的Notification视图
- RemoteViews contentView =
- new RemoteViews(getPackageName(), R.layout.notification);
- contentView.setTextViewText(R.id.textView, "show me when collapsed");
Notification的布局如下所示。
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:gravity="center_horizontal">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/textView"
- android:textColor="#ff43aebe"
- android:gravity="center" />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/imageView"
- android:src="@drawable/robot" />
- </LinearLayout>
通过如下代码,就可以将一个视图指定为Notification正常状态下的视图。
- notification.contentView = contentView;
将另一个展开的布局通过如下代码指定为展开时的视图。
- notification.bigContentView = expandedView;
完整的代码如下所示。
- Intent intent = new Intent(Intent.ACTION_VIEW,
- Uri.parse("http://www.sina.com"));
- PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
- Notification.Builder builder = new Notification.Builder(this);
- builder.setSmallIcon(R.drawable.ic_launcher);
- builder.setContentIntent(pendingIntent);
- builder.setAutoCancel(true);
- builder.setLargeIcon(BitmapFactory.decodeResource(
- getResources(), R.drawable.ic_launcher));
- //通过RemoteViews来创建自定义的Notification视图
- RemoteViews contentView =
- new RemoteViews(getPackageName(),
- R.layout.notification);
- contentView.setTextViewText(R.id.textView,
- "show me when collapsed");
- Notification notification = builder.build();
- //指定视图
- notification.contentView = contentView;
- //通过RemoteViews来创建自定义的Notification视图
- RemoteViews expandedView =
- new RemoteViews(getPackageName(),
- R.layout.notification_expanded);
- //指定视图
- notification.bigContentView = expandedView;
- NotificationManager nm = (NotificationManager)
- getSystemService(NOTIFICATION_SERVICE);
- nm.notify(NOTIFICATION_ID_COLLAPSE, notification);
折叠时,显示效果如图12.37所示。
图12.37 折叠时Notification视图
展开时,显示效果如图12.38所示。
图12.38 展开时Notification视图
12.10.3 悬挂式Notification" class="reference-link">12.10.3 悬挂式Notification
悬挂式Notification是在Android 5.0中新增加的方式,Google希望通过这种方式来给用户带来更好的体验。这种被称为Headsup的Notification方式,可以在屏幕上方产生Notification且不会打断用户操作,能给用户以Notification形式的通知。
在Android Sample中,Google给我们展示了如何完成这样一个效果,代码如下所示。
- Notification.Builder builder = new Notification.Builder(this)
- .setSmallIcon(R.drawable.ic_launcher)
- .setPriority(Notification.PRIORITY_DEFAULT)
- .setCategory(Notification.CATEGORY_MESSAGE)
- .setContentTitle("Headsup Notification")
- .setContentText("I am a Headsup notification.");
- Intent push = new Intent();
- push.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- push.setClass(this, MainActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(
- this, 0, push, PendingIntent.FLAG_CANCEL_CURRENT);
- builder.setContentText("Heads-Up Notification on Android 5.0")
- .setFullScreenIntent(pendingIntent, true);
- NotificationManager nm = (NotificationManager)
- getSystemService(NOTIFICATION_SERVICE);
- nm.notify(NOTIFICATION_ID_HEADSUP, builder.build());
如以上代码所示,通过setFullScreenIntent,我们很轻松地将一个Notification变成了悬挂式Notification,程序显示效果如图12.39所示。
图12.39 悬挂式Notification
12.10.4 显示等级的Notification" class="reference-link">12.10.4 显示等级的Notification
最后一重境界也是在Android 5.X中新加入的一种模式——Notification的显示等级。Android 5.X将Notification分成了三个等级。
- VISIBILITY_PRIVATE——表明只有当没有锁屏的时候会显示
- VISIBILITY_PUBLIC——表明在任何情况下都会显示
- VISIBILITY_SECRET——表明在pin、password等安全锁和没有锁屏的情况下才能够显示
设置Notification等级的方式非常简单,同样是借助builder对象,代码如下所示。
- builder.setVisibility(Notification.VISIBILITY_PUBLIC);
在前面的示例代码中,我们使用了一个RadioGroup来演示VISIBILITY等级,实现代码如下所示。
- RadioGroup radioGroup = (RadioGroup) findViewById(
- visibility_radio_group);
- Notification.Builder builder = new Notification.Builder(this)
- .setContentTitle("Notification for Visibility Test");
- switch (radioGroup.getCheckedRadioButtonId()) {
- case R.id.radio_button_public:
- builder.setVisibility(Notification.VISIBILITY_PUBLIC);
- builder.setContentText("Public");
- builder.setSmallIcon(R.drawable.ic_public);
- break;
- case R.id.radio_button_private:
- builder.setVisibility(Notification.VISIBILITY_PRIVATE);
- builder.setContentText("Private");
- builder.setSmallIcon(R.drawable.ic_private);
- break;
- case R.id.radio_button_secret:
- builder.setVisibility(Notification.VISIBILITY_SECRET);
- builder.setContentText("Secret");
- builder.setSmallIcon(R.drawable.ic_secret);
- break;
- }
- NotificationManager nm = (NotificationManager)
- getSystemService(NOTIFICATION_SERVICE);
- nm.notify(NOTIFICATION_ID_VISIBILITY, builder.build());
代码结构非常清晰,通过build对象的setVisibility方法,就可以轻松地设置Notification显示等级了。
Notification在Android 5.X中的改动非常多,这里只是让大家有一个初步的概念,还有其他的改动,比如以下两种。
增加了设置Notification背景颜色的接口,代码如下所示。
- builder.setColor(Color.RED)
增加了设置Notification的category接口,category用来确定Notification显示的位置,参数就是各种category的类型,代码如下所示。
- builder .setCategory(Notification.CATEGORY_MESSAGE)
