Wear 上の通知スタイル

Wear OS by Google がサポートしている通知スタイルを使用すると、スマートウォッチのユーザー エクスペリエンスが向上します。

一般的な通知スタイルを以下に示します。

  • BIG_TEXT_STYLE
  • BIG_PICTURE_STYLE
  • INBOX_STYLE
  • MESSAGING_STYLE

以下のセクションでは、MESSAGING_STYLEBIG_TEXT_STYLE を通知に追加する方法について説明します。他の通知スタイルを採用する場合は、Wear 通知のサンプルをご覧ください。

以下の関連リソースをご覧ください。

MessagingStyle 通知を作成する

チャット メッセージ アプリをインストールしている場合は、Android 7.0 で追加された NotificationCompat.MessagingStyle を通知に使用する必要があります。Wear は、MessagingStyle 通知に含まれているチャット メッセージを使用して(addMessage() を参照)、チャットアプリに似た高度な機能を展開可能な通知に提供します。

注: MessagingStyle の展開可能な通知を作成するには、ペア設定された Android スマートフォンにバージョン 1.5.0.2861804 以上の Wear コンパニオン アプリがインストールされている必要があります。

スマート リプライ

Wear には、MessagingStyle 通知用にスマート リプライ機能が導入されています。スマート リプライは、展開可能な通知と RemoteInput で、コンテキスト依存のタップ可能な選択肢をユーザーに提供します。 この機能は固定の選択肢リストを強化するものであり、デベロッパーは setChoices() メソッドを使用してこれを RemoteInput に表示できます。

スマート リプライを利用すると、迅速(1 回のタップで済む)、控えめ(大きな声を出さなくてよい)、プライベート(ユーザーが受け取ったメッセージがスマートウォッチから発信されない)、確実(インターネット接続が不要)な方法でチャット メッセージに応答できます。

スマート リプライ応答は、MessagingStyle 通知から提供されたコンテキストを使用して、全面的にスマートウォッチ上で動作する機械学習モデルによって生成されます。スマート リプライ応答を生成するために、Google のサーバーにユーザー通知データが送信されることはありません。

通知アクション用にスマート リプライを有効にするには、次の手順を実施する必要があります。

  1. NotificationCompat.MessagingStyle を使用します。
  2. 通知アクション用の setAllowGeneratedReplies(true) メソッドを呼び出します。
  3. 通知アクションに対して RemoteInput が定義されていることを確認します(ここに応答が格納されます)。

次の例は、スマート リプライ応答を使用する MessagingStyle 通知の作成方法を示しています。

Kotlin

    // Create an intent for the reply action
    val replyPendingIntent = Intent(this, ReplyActivity::class.java).let { replyIntent ->
        PendingIntent.getActivity(this, 0, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT)
    }

    // Create the reply action and add the remote input
    val action = NotificationCompat.Action.Builder(
            R.drawable.ic_reply_icon,
            getString(R.string.label),
            replyPendingIntent
    )
            .addRemoteInput(remoteInput)
            // 1) allow generated replies
            .setAllowGeneratedReplies(true)
            .build()

    val noti = NotificationCompat.Builder(context, channelId)
            .setContentTitle("${messages.size} new messages with $sender")
            .setContentText(subject)
            .setSmallIcon(R.drawable.new_message)
            .setLargeIcon(aBitmap)
            // 2) set the style to MessagingStyle
            .setStyle(
                    NotificationCompat.MessagingStyle(resources.getString(R.string.reply_name))
                            .addMessage(messages[0].text, messages[0].time, messages[0].sender)
                            .addMessage(messages[1].text, messages[1].time, messages[1].sender)
            )
            // 3) add an action with RemoteInput
            .extend(NotificationCompat.WearableExtender().addAction(action)).build()
    

Java

    // Create an intent for the reply action
    Intent replyIntent = new Intent(this, ReplyActivity.class);
    PendingIntent replyPendingIntent =
       PendingIntent.getActivity(this, 0, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    // Create the reply action and add the remote input
    NotificationCompat.Action action =
       new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
       getString(R.string.label), replyPendingIntent)
      .addRemoteInput(remoteInput)
       // 1) allow generated replies
      .setAllowGeneratedReplies(true)
      .build();

    Notification noti = new NotificationCompat.Builder()
        .setContentTitle(messages.length + " new messages with " + sender.toString())
        .setContentText(subject)
        .setSmallIcon(R.drawable.new_message)
        .setLargeIcon(aBitmap)
        // 2) set the style to MessagingStyle
        .setStyle(new NotificationCompat.MessagingStyle(resources.getString(R.string.reply_name))
        .addMessage(messages[0].getText(), messages[0].getTime(), messages[0].getSender())
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getSender()))
        // 3) add an action with RemoteInput
        .extend(new WearableExtender().addAction(action)).build();
    

MessagingStyle 通知に画像を追加する

通知メッセージに画像を追加するには、適切な MIME タイプを設定して、NotificationCompat.MessagingStyle.Message.setData() メソッド内で画像の URI を指定します。

通知に画像データを設定するコード スニペットを以下に示します。

Kotlin

    val message = NotificationCompat.MessagingStyle.Message("sticker", 1, "Jeff")
            .setData("image/png", stickerUri)

    val notification = NotificationCompat.Builder(context, channelId)
            .setStyle(
                    NotificationCompat.MessagingStyle("Me").addMessage(message)
            )
            .build()
    

Java

    NotificationCompat.MessagingStyle.Message message = new Message("sticker", 1, "Jeff")
       .setData("image/png", stickerUri);

    NotificationCompat notification = new NotificationCompat.Builder()
        .setStyle(new NotificationCompat.MessagingStyle("Me")
            .addMessage(message))
        .build();
    

上記のコード スニペットの変数 stickerUri は、一般公開されている場所をポイントする URI です。詳しくは、こちらをご覧ください。

BigTextStyle 通知を作成する

BIG_TEXT_STYLE を使用すると、拡張テキスト コンテンツを通知に挿入できます。ハンドヘルド デバイスでは、通知を展開すると拡張コンテンツが表示されます。ウェアラブル デバイスでは、BigTextStyle を使用するとデフォルトで拡張コンテンツが表示されます。

拡張コンテンツを通知に追加するには、NotificationCompat.Builder オブジェクトで setStyle() を呼び出し、それを BigTextStyle または InboxStyle のいずれかのインスタンスに渡します。

たとえば、次のコードでは、イベントの詳細な説明を含めるために、NotificationCompat.BigTextStyle のインスタンスをイベント通知に追加しています(これにより、setContentText() 用に指定されたスペースに収まり切らないテキストを含めることができます)。

Kotlin

    // Specify the 'big view' content to display the long
    // event description that may not fit the normal content text.
    val bigStyle = NotificationCompat.BigTextStyle().run {
        bigText(eventDescription)
    }

    val notificationBuilder = NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_event)
            .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.notif_background))
            .setContentTitle(eventTitle)
            .setContentText(eventLocation)
            .setContentIntent(viewPendingIntent)
            .addAction(R.drawable.ic_map, getString(R.string.map), mapPendingIntent)
            .setStyle(bigStyle)
    

Java

    // Specify the 'big view' content to display the long
    // event description that may not fit the normal content text.
    BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
    bigStyle.bigText(eventDescription);

    NotificationCompat.Builder notificationBuilder =
        new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_event)
            .setLargeIcon(BitmapFactory.decodeResource(
                    getResources(), R.drawable.notif_background))
            .setContentTitle(eventTitle)
            .setContentText(eventLocation)
            .setContentIntent(viewPendingIntent)
            .addAction(R.drawable.ic_map,
                    getString(R.string.map), mapPendingIntent)
            .setStyle(bigStyle);
    

setLargeIcon() メソッドを使用すると、大きなアイコン画像を任意の通知に追加できます。ただし、このアイコンは、ウェアラブル上では大きな背景画像として表示され、ウェアラブルの画面に合わせて拡大されるため、見た目のバランスが悪くなることがあります。ウェアラブル固有の背景画像を通知に追加する方法については、ウェアラブル固有の機能を通知用に追加するをご覧ください。大きな画像を含む通知をデザインする方法については、Wear OS 向けデザインの原則をご覧ください。

MediaStyle 通知を作成する

NotificationCompat.MediaStyle クラスを使用すると、再生コントロールを通知に追加できます。システム UI がアクティブなメディア セッションを表す通知を識別し、それに応じて応答する(たとえばロック画面にアルバムのアートワークを表示する)には、setMediaSession(MediaSession.Token) メソッドを使用して MediaSession.Token をアタッチします。

注: メディア セッションがアタッチされていないローカル通知で NotificationCompat.MediaStyle を使用した場合、システムはその通知を通常の通知として表示し、メディア スタイルの詳細情報を無視します。