Auto向けメッセージングを提供する
テキストメッセージにより繋がり合い続けられることは多くのドライバーにとって重要です。チャットアプリはユーザーに子供を迎えに行く必要が有ることや夕食の場所が変わったことを伝えることが出来ます。アプリは重要な試合で誰が勝ったかについてスポーツの情報を伝えたり、その他の試合中のゲームについてユーザーの問い合わせに答えることが出来ます。Androidフレームワークによりドライバーをわき見させない標準的なユーザーインターフェイスを用いて、メッセージアプリケーションを拡張させることができます。
メッセージングをサポートするアプリはAutoダッシュボードシステムにメッセージングNotificationを渡すように拡張できます。新着メーッセージがあることを伝え、それに回答できるようにします。
Android携帯デバイスが、接続されたAutoダッシュボードにこれらのサービスを提供するようにあなたのメッセージアプリを構成することが出来ます。接続されたらあなたのアプリはテキストの情報をユーザーに提供し、回答させることが出来ます。AutoダッシュボードシステムはNotificationの表示と回答のためのインターフェイスを取り扱います。
このレッスンではあなたの構築したアプリはチャットアプリのようなメッセージをユーザーに表示し回答を受け取ると仮定します。ここではAutoデバイスでメッセージを表示し返答させるためにアプリを拡張する方法を紹介します。
メッセージングサービスを提供する
メッセージングアプリはAndroidダッシュボードハードウェア上で直接実行されることはありません。それらはAndroidスマートフォンデバイスにインストールされています。Androidスマートフォンデバイスがダッシュボードシステムに接続されるとインストールされたメッセージングアプリはAutoユーザーインターフェイスを通じてメッセージを表示し返答するサービスを提供できるようになります。Autoデバイス向けにアプリがメッセージサービスを提供出来るようにするには
・あなたのアプリのmanifestにAndroid Autoダッシュボードデバイスと互換性があるメッセージサービスが有ることを指し示すように設定する。
・Autoデバイスに表示するために特殊な形式のnotificationを作り送る。
・ユーザーがメッセージを読んだり返答したことを示すIntentを受け取るように設定する。
Manifestを設定する
Autoデバイス向けのメッセージングサービスをサポートし、メッセージアクションを受け取ることを示すようにmanifestを構築する。この章ではAutoデバイス向けのメッセージをサポートするためにmanifestをどのように変更するかについて記載しています。Autoメッセージングのサポートを宣言する
ユーザーがAndroidスマートフォンをAndroidが動くダッシュボードに接続した時、ダッシュボードデバイスはメッセージングなどの自動車に対応したサービスをサポートするアプリを探します。以下のmanifestエントリーでアプリが自動車をサポートしていることを示します。
<application>
...
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
...
<application>
このmanifestエントリーによりAutoのどの機能に対応しているかを示す第二のxmlファイルが参照されます。
アプリでAutoデバイス向けのメッセージングをサポートするためにアプリの開発プロジェクトディレクトリ内のres/xml/にautomotive_app_desc.xmlというxmlファイルを追加し以下のコードを記載します。
<automotiveApp>
<uses name="notification"/>
</automotiveApp>
Autoデバイスのための機能を宣言するより詳細についてはAutoを始めるを見てください。
既読、返信のintentフィルターを宣言する
Autoデバイスは、あなたのアプリで提供されたメッセージをユーザーが呼んだり返信したことを知らせるためにIntentを使用します。あなたのアプリはメッセージを読んだり返信した時のintent typeを宣言してこの情報をAuto devices向けのメッセージングnotificationに追加します。これによりダッシュボードシステムはユーザーがそれらアクションを行った時にあなたのアプリに通知することが出来るようになります。Manifestの中で既読アクションと返信アクションのIntent typeを宣言してBroadcastReceiverでそれらを取り扱います。下のコード例はそれらのintentと関連したreceiverを宣言する方法を示します。
<application>
...
<receiver android:name=".MyMessageReadReceiver">
<intent-filter>
<action android:name="com.myapp.messagingservice.ACTION_MESSAGE_HEARD"/>
</intent-filter>
</receiver>
<receiver android:name=".MyMessageReplyReceiver">
<intent-filter>
<action android:name="com.myapp.messagingservice.ACTION_MESSAGE_REPLY"/>
</intent-filter>
</receiver>
...
</application>
この例にあるBroadcastReceiverクラスについては「ユーザーアクションを取り扱う」で紹介されています。
メッセージング向けのSupport Libraryをインポートする
Autoデバイス向けのnotificationを作るにはv4 support libraryのクラス群が必要です。Android SDK Managerを使ってExtrasのAndroid Support RepositoryをVersion9以上にExtrasのAndroid Support Libraryを21.0.2以上にアップデートします。次にbuild.gradleに以下を追加してAndroid Studioでの開発プロジェクトに更新されたsupport librariesをインポートします。
dependencies {
...
compile 'com.android.support:support-v4:21.0.+'
}
Android Studio以外の開発環境でプロジェクトにSupport libraryを取り込むための方法はSupport Library Setupを見てください。
ユーザーにメッセージを通知する。
メッセージアプリがメッセージを接続したAutoダッシュボードに提供するためにnotificationsフレームワークを使用します。ユーザーに通知するメッセージが有るとき、Dashboardシステムでユーザーに表示するために特別に構築されたnotificationを作ります。Autoデバイスはダッシュボードスクリーンの表示を管理し、メッセージを音声で読み上げることも出来ます。ダッシュボードシステムはまた音声入力でユーザーが返信する時に音声でユーザーと対話の取り扱いも行います。メッセージングユーザーインターフェイスはメッセージの情報について2つのレベルを使ってAutoでユーザーに提示します。Notification最初のレベルはユーザーがどのような会話が利用可能であるか、誰からかを伝えます。コンテンツの内容は含みません。通常、会話は他のユーザーからAutoユーザー向けの1つ以上のメッセージです。
次のレベルのNotificationは会話内の実際のメッセージコンテンツです。ユーザーが会話のメッセージを聞きたいと指示した時、Autoユーザーインターフェイスは音声読み上げを使ってメッセージを再生します。
この章ではAutoユーザーに会話が利用可能で有ることを伝え会話のメッセージコンテンツを提供する方法を紹介します。
会話のメッセージを作る
Auto向けのメッセージングNotificationは会話内のメッセージをNotificationCompat.CarExtender.UnreadConversationクラスを使って管理します。これは特定の送信者から未読や新着の会話を示します。この会話には送り主からのメッセージのリストが含まれます。
次の例のようにしてunread conversion objectを作るためにNotificationCompat.CarExtender.UnreadConversation.Builderを使います。
// Car Notificationで音声入力によるRemote inputを作る。
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(getApplicationContext().getString(R.string.notification_reply))
.build();
// 特定の送信者から送られたメッセージのグループを
// 管理するためにunread conversion objetを作る
UnreadConversation.Builder unreadConvBuilder =
new UnreadConversation.Builder(participantName)
.setReadPendingIntent(msgHeardPendingIntent)
.setReplyAction(replyPendingIntent, remoteInput);
このconversationオブジェクトにはAutoデバイスがアプリにAutoユーザーが会話を読んだことを知らせるためのPendingIntentが含まれています。Intentの形式については「会話の既読、返信Intentを作る」の章で紹介します。
あなたのアプリが会話の返信をサポートしているなら、setReplyAction()メソッドを呼びユーザーアクションを返すためのPending intentを渡す必要があります。NotificationCompat.CarExtender.UnreadConversationオブジェクトにRemoteInputオブジェクトを含める必要もあります。
Autoユーザーが受け取った会話に返信を喋ったら、Remote inputオブジェクトは音声返信をテキストにしてあなたのアプリに受け取らせます。
会話に関連するメッセージ
Autoで提供されるメッセージはNotificationCompat.CarExtender.UnreadConversationクラスを使って会話と関連していなくてはいけません。以下の例は関連する個別のメセージをconversation objectを使って関連させる方法を示します。
// メモ:最も古いものから最新までUnreadConversation.Builderにメッセージを追加する。
for (Iterator<String> messages = conversation.getMessages().iterator();
messages.hasNext(); ) {
String message = messages.next();
unreadConvBuilder.addMessage(message);
}
新しい会話を受信したら、アプリでは関連した会話が既に存在しないかチェックしなくてはいけません。
もし、既に存在する場合は、会話を新しく作る代わりに既に存在する会話に関連付けてください。
会話の既読、返信Intentを作る
Unread conversationオブジェクトは会話を読んだり、返信した時のためのIntentを保持します。それぞれのアクションのPendingIntentを作成することでAuto deviceはアプリにユーザーがそれぞれの会話で行ったアクションを通知できます。
次のコードはAutoユーザーが会話を読んだことをアプリが知る事ができるようにPendingIntentを定義する方法を示しています。
Intent msgHeardIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(com.myapp.messagingservice.ACTION_MESSAGE_HEARD)
.putExtra("conversation_id", conversationId);
PendingIntent msgHeardPendingIntent =
PendingIntent.getBroadcast(getApplicationContext(),
conversationId,
msgHeardIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
この例のconversationIdは現在の会話を表すIntegerです。setAction()の値は「既読、返信のintentフィルターを宣言するで紹介した」あなたのアプリのmanifestに定義したメッセージを受け取るためのIntent filterを表します。
アプリが会話への返信をサポートしているならユーザーが返信したことをアプリに通知するためのPendingIntentも作成します。
次のコード例は各会話でintentを作る方法を紹介しています。
Intent msgReplyIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(com.myapp.messagingservice.ACTION_MESSAGE_REPLY)
.putExtra("conversation_id", conversationId);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
getApplicationContext(),
conversationId,
msgReplyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
ここでもconversationIdは会話を表す一意のIntegerです。
setAction()の値は「既読、返信のintentフィルターを宣言するで紹介した」あなたのアプリのmanifestに定義した返信を取り扱うためのIntent filterを表します。
メッセージを送る
会話のメッセージを受信した時、AutoにNotificationとして送信するために以下の手順を行います。はじめに、この会話向けにNotificationCompat.CarExtender.UnreadConversation.Builderへメッセージを追加しタイムスタンプを更新します。
unreadConvBuilder.addMessage(messageString)
.setLatestTimestamp(currentTimestamp);
次に実際にNotificationを作るときに使うNotificationCompat.Builderを作ります。前のステップで作ったpending intentを使う必要があります。
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.notification_icon)
.setLargeIcon(icon_bitmap)
.setContentText(messageString)
.setWhen(currentTimestamp)
.setContentTitle(participant_name)
.setContentIntent(msgHeardPendingIntent);
NotificationCompat.CarExtenderでNotificationCompat.Builderを継承する必要もあります。今作ったbuilderを使って実際にNotificationCompat.CarExtender.UnreadConversationを作り、NotificationCompat.CarExtenderにアタッチします。
notificationBuilder.extend(new CarExtender()
.setUnreadConversation(unreadConvBuilder.build());
最後にnotificationを送るためにあなたのアプリのNotificationManagerCompatを使用します。
notificationBuilder.extend(new CarExtender()
.setUnreadConversation(unreadConvBuilder.build());
ユーザーアクションを取り扱う
Autoユーザーインターフェイスを通して会話のメッセージをユーザーが読んだ時、ダッシュボードデバイスはあなたのアプリが定義したメッセージングNotificationに基づく方法で、既読Intentを送ります。あなたのアプリはそのIntentを受け取って関連したbroadcast receiverクラスが実行されるか、Serviceのメソッドがアクションを取り扱うためにセットアップされます。次のコードはメッセージの既読Intentの受信を取り扱うBroadcastReceiverクラスを定義する法法を紹介しています。
public class MessageHeardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 「会話の既読、返信Intentを作る」で紹介した方法で
// セットアップを行っていた場合
// 以下を呼び出しconversation IDが取得できます
int conversationId = intent.getIntExtra("conversation_id", -1);
// 読まれたNotificationを表示から削除し、アプリにある
// unread conversationsのリストを更新する。
}
}
Notificationは読まれた時にcancel(int)にnotification IDを渡して呼ぶことで取り除く事ができます。
あなたのアプリはnotifiationで既読としてメッセージをマークしなくてはいけません。
メモ:この実装方法の代わりにPendingIntentでServiceを使う事もできます。
返信アクションを取り扱う
ユーザーがAutoユーザーインターフェイスを介してメッセージングに返信した時、ダッシュボードシステムはあなたのアプリが定義したメッセージnotificationに基づく方法で返信Intentを送ります。あなたのアプリはそのIntentを受け取って関連したbroadcast receiverクラスが実行されるか、Serviceのメソッドがアクションを取り扱うためにセットアップされます。次のコードはメッセージの返信Intentの受信を取り扱うBroadcastReceiverクラスを定義する法法を紹介しています。
public class MessageReplyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 「会話の既読、返信Intentを作る」で紹介した方法で
// セットアップを行っていた場合
// 以下を呼び出しconversation IDが取得できます。
int conversationId = intent.getIntExtra("conversation_id", -1).
}
/**
* intentからテキストメッセージを取得する。
* メモ:RemoteInputのプロセスで
* RemoteInput.getResultsFromIntent()を呼ばなくてはいけません。
*/
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput =
RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
return remoteInput.getCharSequence("extra_voice_reply");
}
return null;
}
}
Except as noted, this content is licensed under Creative Commons Attribution 2.5. For details and restrictions, see the Content License.