バブルにより、ユーザーは会話を簡単に見たり、会話に参加したりできます。
バブルは通知システムに組み込まれています。他のアプリ コンテンツの上にフロート表示し、ユーザーがどこに行ってもユーザーの操作に従います。バブルを開くと、アプリのコンテンツが表示され、操作できます。また、使用していないときは閉じることができます。
デバイスがロックされている場合、または「常に表示状態のディスプレイ」が有効になっている場合は、通常の通知と同様にバブルが表示されます。
バブルは、オプトアウト式の機能です。アプリが最初のバブルを表示すると、権限ダイアログに次の 2 つの選択肢が表示されます。
- アプリからすべてのバブルをブロックします。通知はブロックされませんが、バブルとして表示されることはありません。
- アプリからのすべてのバブルを許可します。
BubbleMetaData
で送信されたすべての通知は、バブルとして表示されます。
バブル API
バブルは通知 API を使用して作成されるため、通常どおり通知を送信します。通知をバブルとして表示するには、通知に追加データを追加します。
バブルの展開ビューは、選択したアクティビティから作成されます。バブルとして適切に表示されるようにアクティビティを構成します。アクティビティはサイズ変更が可能で、埋め込まれている必要があります。これらの要件のいずれかが満たされていない場合は、通知として表示されます。
次のコードは、バブルを実装する方法を示しています。
<activity
android:name=".bubbles.BubbleActivity"
android:theme="@style/AppTheme.NoActionBar"
android:label="@string/title_activity_bubble"
android:allowEmbedded="true"
android:resizeableActivity="true"
/>
アプリに同じタイプのバブルが複数表示される場合(連絡先が異なる複数のチャット会話など)は、アクティビティで複数のインスタンスを起動できる必要があります。Android 10 以前を搭載しているデバイスでは、documentLaunchMode
を明示的に "always"
に設定しない限り、通知はバブルとして表示されません。Android 11 以降では、すべての会話の documentLaunchMode
が自動的に "always"
に設定されるため、この値を明示的に設定する必要はありません。
バブルを送信する手順は次のとおりです。
- 通常どおりに通知を作成します。
BubbleMetadata.Builder(PendingIntent, Icon)
またはBubbleMetadata.Builder(String)
を呼び出してBubbleMetadata
オブジェクトを作成します。setBubbleMetadata()
を使用してメタデータを通知に追加します。- Android 11 以降をターゲットとしている場合は、バブルのメタデータまたは通知が共有ショートカットを参照していることを確認してください。
手順を次の例に示します。
Kotlin
// Create a bubble intent. val target = Intent(context, BubbleActivity::class.java) val bubbleIntent = PendingIntent.getActivity(context, 0, target, 0 /* flags */) val category = "com.example.category.IMG_SHARE_TARGET" val chatPartner = Person.Builder() .setName("Chat partner") .setImportant(true) .build() // Create a sharing shortcut. val shortcutId = generateShortcutId() val shortcut = ShortcutInfo.Builder(mContext, shortcutId) .setCategories(setOf(category)) .setIntent(Intent(Intent.ACTION_DEFAULT)) .setLongLived(true) .setShortLabel(chatPartner.name) .build() // Create a bubble metadata. val bubbleData = Notification.BubbleMetadata.Builder(bubbleIntent, Icon.createWithResource(context, R.drawable.icon)) .setDesiredHeight(600) .build() // Create a notification, referencing the sharing shortcut. val builder = Notification.Builder(context, CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(smallIcon) .setBubbleMetadata(bubbleData) .setShortcutId(shortcutId) .addPerson(chatPartner)
Java
// Create a bubble intent. Intent target = new Intent(mContext, BubbleActivity.class); PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0 /* flags */); private val CATEGORY_TEXT_SHARE_TARGET = "com.example.category.IMG_SHARE_TARGET" Person chatPartner = new Person.Builder() .setName("Chat partner") .setImportant(true) .build(); // Create a sharing shortcut. private String shortcutId = generateShortcutId(); ShortcutInfo shortcut = new ShortcutInfo.Builder(mContext, shortcutId) .setCategories(Collections.singleton(CATEGORY_TEXT_SHARE_TARGET)) .setIntent(Intent(Intent.ACTION_DEFAULT)) .setLongLived(true) .setShortLabel(chatPartner.getName()) .build(); // Create a bubble metadata. Notification.BubbleMetadata bubbleData = new Notification.BubbleMetadata.Builder(bubbleIntent, Icon.createWithResource(context, R.drawable.icon)) .setDesiredHeight(600) .build(); // Create a notification, referencing the sharing shortcut. Notification.Builder builder = new Notification.Builder(mContext, CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(smallIcon) .setBubbleMetadata(bubbleData) .setShortcutId(shortcutId) .addPerson(chatPartner);
バブルの送信時にアプリがフォアグラウンドにある場合は、ユーザーがアプリからバブルまたは通知をブロックしない限り、重要度は無視され、バブルは常に表示されます。
展開されたバブルを作成する
バブルは、展開された状態で自動的に表示されるように設定することができます。この機能は、ボタンをタップして新しいチャットを開始するなど、バブルが表示されるアクションをユーザーが行う場合にのみ使用することをおすすめします。この場合、バブルの作成時に最初に送信される通知も抑制するのが合理的です。
これらの動作を有効にするフラグを設定するには、setAutoExpandBubble()
と setSuppressNotification()
のメソッドを使用できます。
次の例は、展開された状態で自動的に表示されるバブルを設定する方法を示しています。
Kotlin
val bubbleMetadata = Notification.BubbleMetadata.Builder() .setDesiredHeight(600) .setIntent(bubbleIntent) .setAutoExpandBubble(true) .setSuppressNotification(true) .build()
Java
Notification.BubbleMetadata bubbleData = new Notification.BubbleMetadata.Builder() .setDesiredHeight(600) .setIntent(bubbleIntent) .setAutoExpandBubble(true) .setSuppressNotification(true) .build();
バブル コンテンツのライフサイクル
バブルが展開されると、コンテンツ アクティビティは通常のプロセス ライフサイクルを通過し、アプリがフォアグラウンド プロセスになります(まだフォアグラウンドになっていない場合)。
バブルが閉じられるか閉じられると、アクティビティは破棄されます。これにより、アプリで他のフォアグラウンド コンポーネントが実行されているかどうかによって、プロセスがキャッシュに保存され、後で強制終了される可能性があります。
バブルが表示されるタイミング
ユーザーの作業を中断しないように、バブルは特定の状況でのみ表示されます。
Android 11 以降をターゲットとするアプリの場合、会話の要件を満たしていない限り、通知はバブルとして表示されません。Android 10 以前をターゲットとするアプリでは、次の条件の 1 つ以上が満たされている場合にのみ、通知がバブルとして表示されます。
- 通知で
MessagingStyle
が使用され、Person
が追加されている。 - 通知は
Service.startForeground
の呼び出しで、category
がCATEGORY_CALL
で、Person
が追加されています。 - 通知の送信時にアプリがフォアグラウンドで実行されている。
これらの条件がいずれも満たされない場合は、バブルの代わりに通知が表示されます。
バブルからアクティビティを起動する
バブルが新しいアクティビティを起動すると、新しいアクティビティは、同じタスクと同じバブル ウィンドウ内で起動されるか、全画面表示の新しいタスクで、起動したバブルが閉じられます。
バブルと同じタスクで新しいアクティビティを起動するには:
1. インテント(activity.startActivity(intent)
、1)を起動するときにアクティビティ コンテキストを使用します。インテントに FLAG_ACTIVITY_NEW_TASK
フラグを設定しないでください。
それ以外の場合は、新しいアクティビティが新しいタスクで開始され、バブルが閉じられます。
バブルは特定の会話を表すため、バブル内で起動するアクティビティは、その会話に関連している必要があります。また、バブル内でアクティビティを起動すると、バブルのタスクスタックが増え、特にナビゲーションに関して、ユーザー エクスペリエンスが複雑になる可能性があります。
おすすめの方法
- 通知が重要な場合にのみバブルとして送信します。たとえば、通知が進行中の通信の一部である場合や、ユーザーが明示的にバブルをリクエストした場合です。バブルは、画面全体に表示され、他のアプリ コンテンツを覆います。
- バブル通知が通常の通知としても機能することを確認します。ユーザーがバブルを無効にすると、バブル通知が通常の通知として表示されます。
- バブル アクティビティで
onBackPressed
をオーバーライドするときに、super.onBackPressed
を呼び出します。そうしないと、バブルが正しく動作しない可能性があります。
折りたたまれたバブルが更新されたメッセージを受け取ると、未読メッセージを示すバッジアイコンがバブルに表示されます。ユーザーが関連付けられたアプリでメッセージを開いたら、次の手順を行います。
BubbleMetadata
を更新して、通知を抑制します。BubbleMetadata.Builder.setSuppressNotification()
を呼び出します。これにより、ユーザーがメッセージを操作したことを示すバッジアイコンが削除されます。BubbleMetadata
の更新に伴う音やバイブレーションを抑制するには、Notification.Builder.setOnlyAlertOnce()
をtrue
に設定します。
サンプルアプリ
People サンプルアプリは、バブルを使用する会話アプリです。このデモでは chatbot を使用します。実際のアプリケーションでは、人間によるメッセージにバブルを使用します。