为可穿戴设备创建Notification

编写:wangyachen - 原文: http://developer.android.com/training/wearables/notifications/creating.html

使用 NotificationCompat.Builder 来创建可以发送给可穿戴设备的手持设备Notification。当我们使用这个类创建Notification之后,无论Notification出现在手持式设备上还是可穿戴设备上,系统都会把Notification正确地显示出来。

Note:使用 RemoteViews 的Notification会剥除自定义的 layout,并且可穿戴设备上只显示文本和图标。但是,通过创建一个运行在可穿戴设备上的应用,开发者能够使用自定义的卡片布局创建自定义Notifications

Import必要的类

为了引入必要的包,在我们的 build.gradle 文件中加入如下内容:

  1. compile "com.android.support:support-v4:20.0.+"

现在我们的项目能够访问关键的包,接下来从support library中引入必要的类:

  1. import android.support.v4.app.NotificationCompat;
  2. import android.support.v4.app.NotificationManagerCompat;
  3. import android.support.v4.app.NotificationCompat.WearableExtender;

通过Notification Builder创建Notification

v4 support library能够让开发者使用最新的特性去创建 Notification,诸如action 按钮和大的图标,而且兼容Android1.6(API level4)及以上的版本。

为了通过support library创建一个Notification,我们需要创建一个 NotificationCompat.Builder 的实例,然后通过将该实例传给 notify()) 来发出 Notification。例如:

  1. int notificationId = 001;
  2. // Build intent for notification content
  3. Intent viewIntent = new Intent(this, ViewEventActivity.class);
  4. viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
  5. PendingIntent viewPendingIntent =
  6. PendingIntent.getActivity(this, 0, viewIntent, 0);
  7. NotificationCompat.Builder notificationBuilder =
  8. new NotificationCompat.Builder(this)
  9. .setSmallIcon(R.drawable.ic_event)
  10. .setContentTitle(eventTitle)
  11. .setContentText(eventLocation)
  12. .setContentIntent(viewPendingIntent);
  13. // Get an instance of the NotificationManager service
  14. NotificationManagerCompat notificationManager =
  15. NotificationManagerCompat.from(this);
  16. // Build the notification and issues it with notification manager.
  17. notificationManager.notify(notificationId, notificationBuilder.build());

当该Notification出现在手持设备上时,用户能够通过触摸Notification来触发之前通过setContentIntent()设置的PendingIntent。当该Notification出现在可穿戴设备上时,用户能够通过向左滑动该Notification显示Open的action,点击这个action能够激活手持设备上的Intent。

添加Action按钮

除了通过 setContentIntent()) 定义的主要内容action之外,我们还可以通过传递一个 PendingIntentaddAction()) 来添加其它action。

创建Notification - 图1

例如,下面的代码展示了创建一个同之前相仿的Notification,只不过添加了一个在地图上查看事件位置的action。

  1. // Build an intent for an action to view a map
  2. Intent mapIntent = new Intent(Intent.ACTION_VIEW);
  3. Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
  4. mapIntent.setData(geoUri);
  5. PendingIntent mapPendingIntent =
  6. PendingIntent.getActivity(this, 0, mapIntent, 0);
  7. NotificationCompat.Builder notificationBuilder =
  8. new NotificationCompat.Builder(this)
  9. .setSmallIcon(R.drawable.ic_event)
  10. .setContentTitle(eventTitle)
  11. .setContentText(eventLocation)
  12. .setContentIntent(viewPendingIntent)
  13. .addAction(R.drawable.ic_map,
  14. getString(R.string.map), mapPendingIntent);

在手持设备上,action表现为在Notification上附加的一个额外按钮。而在可穿戴设备上,action表现为Notification左滑后出现的大按钮。当用户点击action时,能够触发手持设备上对应的intent。

Tip:如果我们的Notification包含了一个”回复”的action(例如短信类app),我们可以通过支持直接从Android可穿戴设备返回的语音输入,来加强该功能的体验。更多信息,详见在Notification中接收语音输入

可穿戴式独有的 Actions

如果开发者想要可穿戴式设备上的action与手持式设备不一样的话,可以使用 WearableExtender.addAction()),一旦我们通过这种方式添加了action,可穿戴式设备便不会显示任何其他通过 NotificationCompat.Builder.addAction()) 添加的action。这是因为,只有通过 WearableExtender.addAction()) 添加的action才能只在可穿戴设备上显示且不在手持式设备上显示。

  1. // Create an intent for the reply action
  2. Intent actionIntent = new Intent(this, ActionActivity.class);
  3. PendingIntent actionPendingIntent =
  4. PendingIntent.getActivity(this, 0, actionIntent,
  5. PendingIntent.FLAG_UPDATE_CURRENT);
  6. // Create the action
  7. NotificationCompat.Action action =
  8. new NotificationCompat.Action.Builder(R.drawable.ic_action,
  9. getString(R.string.label, actionPendingIntent))
  10. .build();
  11. // Build the notification and add the action via WearableExtender
  12. Notification notification =
  13. new NotificationCompat.Builder(mContext)
  14. .setSmallIcon(R.drawable.ic_message)
  15. .setContentTitle(getString(R.string.title))
  16. .setContentText(getString(R.string.content))
  17. .extend(new WearableExtender().addAction(action))
  18. .build();

添加一个Big View

开发者可以在Notification中通过添加某种”big view”风格来插入扩展文本。在手持式设备上,用户能够通过展开Notification看见big view的内容。在可穿戴式设备上,big view内容是默认可见的。

创建Notification - 图2

可以通过 NotificationCompat.Builder 对象调用 setStyle()),并设置参数为 BigTextStyleInboxStyle 的实例,从而将扩展内容添加到 Notification 中。

比如,下面的代码为事件 Notification 添加了一个 NotificationCompat.BigTextStyle 的实例,目的是为了包含完整的事件描述(这能够包含比 setContentText()) 提供的空间所能容纳的字数更多的文字)。

  1. // Specify the 'big view' content to display the long
  2. // event description that may not fit the normal content text.
  3. BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
  4. bigStyle.bigText(eventDescription);
  5. NotificationCompat.Builder notificationBuilder =
  6. new NotificationCompat.Builder(this)
  7. .setSmallIcon(R.drawable.ic_event)
  8. .setLargeIcon(BitmapFractory.decodeResource(
  9. getResources(), R.drawable.notif_background))
  10. .setContentTitle(eventTitle)
  11. .setContentText(eventLocation)
  12. .setContentIntent(viewPendingIntent)
  13. .addAction(R.drawable.ic_map,
  14. getString(R.string.map), mapPendingIntent)
  15. .setStyle(bigStyle);

要注意的是,开发者可以通过 setLargeIcon()) 方法为任何 Notification 添加一个大图标。但是,这些图标在可穿戴设备上会显示成大的背景图片,并且由于这些图标会被放大以适应可穿戴设备的屏幕,导致这些图标显示的效果不好。想要为 Notification 添加一个可穿戴设备适用的背景图片,请看下面一小节为 Notification 添加可穿戴式特性。更多关于大图片在 Notification 上的设计,详见 Design Principles of Android Wear

为Notification添加可穿戴式特性

如果我们需要为 Notification 添加一些可穿戴式的特性设置,比如制定额外的内容页,或者让用户通过语音输入一些文字,那么我们可以使用
NotificationCompat.WearableExtender 来制定这些设置。为了适用这个 API,我们需要:

  1. 创建一个 WearableExtender 的实例,为 Notification 设置可穿戴设备独有的特性。
  2. 创建一个 NotificationCompat.Builder 的实例,就像本课程先前所说的,设置需要的 Notification 属性。
  3. 调用 Notification 上的 extend()) 并将 WearableExtender 传进该方法。这在 Notification 上应用了可穿戴设备的选项。
  4. 调用 build()) 去构建一个 Notification。

例如,以下代码调用 setHintHideIcon()) 方法把应用的图标从 Notification 卡片上删掉。

  1. // Create a WearableExtender to add functionality for wearables
  2. NotificationCompat.WearableExtender wearableExtender =
  3. new NotificationCompat.WearableExtender()
  4. .setHintHideIcon(true)
  5. .setBackground(mBitmap);
  6. // Create a NotificationCompat.Builder to build a standard notification
  7. // then extend it with the WearableExtender
  8. Notification notif = new NotificationCompat.Builder(mContext)
  9. .setContentTitle("New mail from " + sender)
  10. .setContentText(subject)
  11. .setSmallIcon(R.drawable.new_mail)
  12. .extend(wearableExtender)
  13. .build();

setHintHideIcon()) 和 setBackground()) 这两个方法是 NotificationCompat.WearableExtender 可用的新 Noticication 特性的两个例子。

Note:setBackground()) 中使用的位图在不滚动的背景下应该是 400x400 的分辨率,在支持视差滚动的背景下应该是 640x640。将这些位图放在 res/drawable-nodpi 目录下。将可穿戴 Notification 中使用的其它不是位图的资源放到 res/drawable-hdpi 目录,例如 setContentIcon()) 用到的那些资源。

如果开发者需要稍后去读取可穿戴特性的设置,可以使用设置相应的get方法,该例子通过调用 getHintHideIcon()) 去获取当前 Notification 是否隐藏了图标。

  1. NotificationCompat.WearableExtender wearableExtender =
  2. new NotificationCompat.WearableExtender(notif);
  3. boolean hintHideIcon = wearableExtender.getHintHideIcon();

传递 Notification

如果开发者想要传递自己的 Notification,请使用 NotificationManagerCompat 的API代替 NotificationManager

  1. // Get an instance of the NotificationManager service
  2. NotificationManagerCompat notificationManager =
  3. NotificationManagerCompat.from(mContext);
  4. // Issue the notification with notification manager.
  5. notificationManager.notify(notificationId, notif);

如果开发者使用了framework中的 NotificationManager ,那么 NotificationCompat.WearableExtender 中的一些特性就会失效,所以,请确保使用 NotificationManagerCompat

下一课:在 Notifcation 中接收语音输入