Messaging API と People API を使用して Android アプリにチャット関連の機能を追加する

1. 始める前に

メッセージング アプリの作成は容易な作業ではありません。全体的なユーザー エクスペリエンスは主観的なものなります。Android では、チャット エクスペリエンスを向上させ、簡素化できるように Messaging API と People API が用意されています。

この Codelab では、これらの API を使用して、Android のチャットアプリに魅力的なエコシステムを作成する方法について学びます。ここでは JetChat アプリを拡張します。これは、Jetpack Compose を使用して基本的な機能のみを備えたチャットアプリです。

前提条件

  • Android 開発に関する基本的な知識
  • 通知に関する基本的な知識

作成するアプリの概要

次の処理を実行するように拡張した JetChat アプリ:

  • 通知ドロワーの予約済みの会話セクションに、会話を表す通知を表示する。
  • これらの通知の共有ターゲットを参照して、アプリの会話を共有できるようにする。
  • これらのオブジェクトを作成するベスト プラクティスを実施し、アプリを強化するシステムから提供されるデフォルトのエクスペリエンスを利用する。

学習内容

  • 通知ドロワーの予約済みの会話セクションに会話関連の通知を表示する方法を学習する。
  • Messaging API および People API で有効になるさまざまなエクスペリエンスをについて理解する。

必要なもの

  • Git
  • Android Studio
  • GitHub アカウント

2. 設定する

出発点は JetChat アプリです。スターター コードを使用して JetChat アプリを拡張し、Messaging API と People API の機能を理解します。

スターター コードを取得する

この Codelab のスターター コードを取得するには、次の操作を行います。

  1. コマンドラインから、次の GitHub リポジトリのクローンを作成します。
git clone –branch starter-code \
https://github.com/android/people-messaging-codelab.git
  1. Android Studio でプロジェクトを開き、[a1bbb9d97659a043.png Run app] をクリックします。[Emulator] ペインが開き、アプリが表示されます。

拡張された JetChat アプリを確認する

  1. アプリの [Message #composers] テキスト ボックスにメッセージを入力して、[Send] をタップします。
  2. アプリから移動します。数秒後、チャットの応答を含むプッシュ通知を受信します。

3. 会話通知を作成する

Android 11 で導入された API を使用すると、通知ドロワーの特定のセクションにチャット関連の通知(厳密にいうと会話)を表示できます。

ステータスバーから下にスワイプして表示される通知ドロワー

通知は、Notification.MessagingStyle クラスで、長期共有シュートカットを参照する必要があります。このセクションでは、これらの API 要件を満たし、会話セクションに会話を表す通知を表示する方法について学習します。

通知を NotificationCompat.MessagingStyle クラスにするには、次の操作を行います。

  1. Android Studio の [Project] タブで、[app] > [java] > [com.example.compose.jetchat] > [conversation] をクリックして、[ConversationFragment] をダブルクリックします。
  2. ConversationFragment.kt ファイルで ConversationFragment クラスを探し、createNotification 関数で通知が作成される Notification コードブロックを確認します。
  3. setContentText メソッドを setStyle メソッドで置き換えます。これにより、通知のスタイルが NotificationCompat.MessagingStyle クラスに設定されます。このヘルパークラスは、setContextText メソッドで設定されたメッセージを関連するコンテキスト(メッセージの送信時間や送信者など)と一緒に追加します。

ConversationFragment.kt

private fun createNotification(
   notificationId: Int,
   message: Message,
   person: Person,
   shortcut: ShortcutInfoCompat,
   time: Long
): Notification? {
    ...
    .setStyle(NotificationCompat.MessagingStyle(person).addMessage(
                      NotificationCompat.MessagingStyle.Message(
                          message.content,
                          time,
                          person
                      )
    )
    )
    ...
    .build()
}

アプリを実行する

  1. アプリを実行します。
  2. アプリの [Message #composers] テキスト ボックスにメッセージを入力して、[Send] をタップします。
  3. アプリから移動します。プッシュ通知を再度受信しますが、スタイルが異なります。メッセージのアバターと別のスタイルが含まれています。この通知を所定の場所に表示するには、まだ作業が必要です。

4. 会話の共有ターゲットを作成する

通知で共有ショートカットまたは共有ターゲットを参照する必要があります。共有ターゲットは、shortcuts.xml ファイルに定義されています。これは、プログラムで定義されるショートカットのエントリポイントになります。作成するショートカットはアプリ内で会話を表、これにより、会話でのコンテンツの共有が可能になります。

共有ターゲットを定義する

  1. [Project] タブで res ディレクトリを右クリックし、[New] > [Directory] を選択します。
  2. テキスト ボックスに「xml」と入力して、Enter を押します(macOS の場合は return)。
  3. xml ディレクトリを右クリックして、[File] を選択します。
  4. テキスト ボックスに「shortcuts.xml」と入力して、Enter を押します(macOS の場合は return)。
  5. shortcuts.xml ファイルで、text/plain 型データの共有を処理する共有ターゲットを宣言します。

shortcuts.xml

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <share-target android:targetClass="com.example.compose.jetchat.NavActivity">
   <data android:mimeType="text/plain" />
   <category android:name="com.example.compose.jetchat.share.TEXT_SHARE_TARGET" />
 </share-target>
</shortcuts>
  1. [Project] タブで [manifests] をクリックして、[AndroidManifest.xml] をダブルクリックします。
  2. AndroidManifest.xml ファイルで、shortcuts.xml ファイルを定義します。

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.compose.jetchat">

   <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.Jetchat.NoActionBar">
...
 <meta-data android:name="android.app.shortcuts"
            android:resource="@xml/shortcuts" />

    </application>
</manifest>
  1. AndroidManifest.xml ファイルの activity コンポーネントで、共有ロジックを含むインテント フィルタを定義します。

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.compose.jetchat">

   ...
       <activity
           ...
           <intent-filter>
               <action android:name="android.intent.action.SEND" />
               <category android:name="android.intent.category.DEFAULT" />
               <data android:mimeType="text/plain" />
           </intent-filter>
...

ショートカットを定義する

通知ごとに、関連するショートカットを関連付ける必要があります。固有のショートカットが 1 人の共有相手を表すため、会話ごとに固有のショートカットを定義します。

ショートカットを生成するには、次の操作を行います。

  1. [プロジェクト] タブで、[app] > [java] > [com.example.compose.jetchat] > [conversation] > [util] をクリックして、[ConversationUtil] をダブルクリックします。
  2. ConversationUtil.kt ファイルで、generateShortcut 関数を追加します。

ConversationUtil.kt

import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import com.example.compose.jetchat.NavActivity

class ConversationUtil {

   companion object {
...
fun generateShortcut(context: Context, shortcutId: String): ShortcutInfoCompat {
   return ShortcutInfoCompat.Builder(context, shortcutId)
   .setCategories(setOf(CATEGORY_SHARE))
   .setLongLived(true)
   .setShortLabel(shortcutId)
   .setLongLabel(shortcutId)
   .setIntent(
       Intent(context, NavActivity::class.java)
           .setAction(Intent.ACTION_VIEW)
   )
   .build()
}

この関数には、会話に必要な setPerson メソッドと setLongLived メソッドが含まれています。ショートカットに関連付けられた人物が会話の相手になります。long-lived を true 値に設定することで、このショートカットがキャッシュに保存され、UI のさまざまなサーフェスに表示されます。

通知でショートカットを参照する

通知で共有ショートカットを参照する必要があります。ただし、ショートカットの作成は、通知をプッシュする前に行う必要があります。

方法は次のとおりです。

  1. ConversationFragment.kt ファイルで ConversationFragment クラスを探します。
  2. notification 変数呼び出しの前に、ConversationUtil.generateShortcut から生成されたショートカットを参照する shortcut 変数を作成します。
  3. notification 変数の createNotification メソッドで、パラメータとして nullshortcut 変数に置き換えます。

ConversationFragment.kt

private fun simulateResponseAsANotification() {
   ...
   if (message.author != "me") {
       ...
       val shortcut = ConversationUtil.generateShortcut(context!!, message.author)
       val notification = createNotification(notificationId, message, person, shortcut, time)
       ...
   }
}
  1. createNotification メソッドで、NotificationCompat.Builder#setShortcutInfo メソッドを追加し、パラメータとして shortcut 変数を渡します。

ConversationFragment.kt

private fun createNotification(
  notificatoinIf: Int,
  messagin: Message,
  person: Person,
  shortcut: ShortcutInfoCompat?,
  time: Long
): Notification {
...
return NotificationCompat.Builder(context!!,  ConversationUtil.CHANNEL_MESSAGES)
   ...
   .setShortcutInfo(shortcut)
   .build()
}

ショートカットを公開する

  • ショートカットを公開するには、simulateResponseAsANotification 関数の notificationManager.notify メソッドの前に pushDynamicShortcut メソッドを呼び出します。

ConversationFragment.kt

import androidx.core.content.pm.ShortcutManagerCompat

...private fun simulateResponseAsANotification() {
   ...
   if (message.author != "me") {
       ...
       ShortcutManagerCompat.pushDynamicShortcut(context!!, shortcut)
       ...
   }
}

アプリを実行する

  1. アプリを実行します。
  2. アプリの [Message #composers] テキスト ボックスにメッセージを入力して、[Send] をタップします。
  3. アプリから移動します。プッシュ通知を再度受信しますが、会話関連の通知とはスタイルがかなり異なります。アバター アイコンは特に顕著で、アプリのアイコンと統合されています。送信者、時刻、テキストもより簡素化されています。

5. オプション: バブルを有効にする

バブルは Android 9 で導入されました。Android 11 では会話コンテキストで使用できるように改善されています。バブルは、会話のアバターとして機能する丸いオーバーレイです。バブルはアプリ ランチャーに表示され、開いたバブルで簡単に会話に応答することができます。バブルが実装されていても、ユーザーの好みにもよるため、この機能はオプションになっています。

バブルを有効にするには、次の操作を行います。

  1. AndroidManifest.xml ファイルで、allowEmbedded 属性と resizeableActivity 属性を追加し、それぞれに true 値を設定します。

AndroidManifest.xml

<activity
  ...
  android:allowEmbedded="true"
  android:resizeableActivity="true"
  ...
</activity>
  1. ConversationUtil.kt ファイルの ConversationUtil クラスで、バブル メタデータを追加します。

ConversationUtil.kt

import androidx.core.app.NotificationCompat
import androidx.core.graphics.drawable.IconCompat

fun createBubbleMetadata(context: Context, icon: IconCompat): NotificationCompat.BubbleMetadata {
        // Create bubble intent
        val target = Intent(context, NavActivity::class.java)
        val bubbleIntent = PendingIntent.getActivity(context, REQUEST_BUBBLE, target, flagUpdateCurrent(mutable = true))

        // Create bubble metadata
        return NotificationCompat.BubbleMetadata.Builder(bubbleIntent, icon)
            .setDesiredHeight(400)
            .setSuppressNotification(true)
            .build()
    }
  1. ConversationFragment.kt ファイルでバブルのメタデータを作成し、通知で参照します。

ConversationFragment.kt

private fun createNotification(
  notificatoinIf: Int,
  messagin: Message,
  person: Person,
  shortcut: ShortcutInfoCompat?,
  time: Long
): Notification {
...
// Reference the bubble metadata in the notification.
  return NotificationCompat.Builder(context!!,     ConversationUtil.CHANNEL_MESSAGES)
    ...
     .setBubbleMetadata(ConversationUtil.createBubbleMetadata(context!!, person.icon!!))
...
    .build()
}

アプリを実行する

  1. アプリを実行します。
  2. アプリの [Message #composers] テキスト ボックスにメッセージを入力して、[Send] をタップします。
  3. アプリから移動します。数秒後、チャットからの通知がバブル形式で表示されます。
  4. バブルをタップします。バブルから会話が開始します。

会話バブル

6. オプション: リンクを共有する

共有ターゲットを宣言し、通知で参照しました。これにより、通知が Sharesheet の連絡先に表示されるようになりました。また、ACTION インテントの送信時にボトムアップ コンポーネントが表示されます。共有ターゲットは Sharesheet の先頭に表示されます。これにより、会話で豊富なコンテンツを共有することが可能になります。

Sharesheet を呼び出すには、次の操作を行います。

  1. デバイスで Google Chrome を開き、任意のウェブページ(developer.android.com など)に移動します。
  2. 必要であれば、[2fdbaccda71bc5f0.png More vert] をクリックします。
  3. [771b0be21764f6b6.png共有] をクリックします画面の下部に Sharesheet が表示されます。

Sharesheet

  1. 可能であれば、[468248e6b8a84bb3.png JetChat] をクリックします。チャットで URL が共有されます。
  2. [468248e6b8a84bb3.png JetChat] が表示されない場合は、[145399af71577431.png More] をクリックして、システムの Sharesheet を呼び出し、ShareSheet を上にスワイプして [468248e6b8a84bb3.png JetChat] をクリックします。チャットで URL が共有されます。

これはシンプルな例です。より多くのコンテンツ タイプを共有できます。詳しくは、他のアプリからのシンプルなデータ取得をご覧ください。

7. 完了

これで完了です。ここでは、Messaging API と People API を使用して、チャット関連の機能を Android アプリに追加する方法が学習しました。メッセージングをお楽しみください。

詳細