Autoのためのオーディオ再生を提供する

2014/12/23 5490hit

Auto向けの音楽再生機能を提供する。

原文
Android Auto向けのアプリを作る目次

ドライバーは運転中に彼らの音楽やオーディオコンテンツにアクセスしたいと考えています。オーディオブック、ポッドキャスト、スポーツ実況、録音された対話は長旅を教育的に、感動的に、楽しくします。
Androidフレームワークはあなたのアプリを拡張して、シンプルで安全なユーザーインターフェイスを使ってユーザーが彼らのお気に入りの音楽やオーディオコンテンツを聴くことが出来るようにします。

Android5.0以上のモバイル機器で動いているアプリは音声サービスをAndroid Autoが実行しているダッシュボードシステムに提供できます。
あなたのアプリにいくつかの設定を行い音楽トラックにアクセスするためのサービスを実装することでAutoデバイスであなたのアプリを見つけて、アプリのオーディオコンテンツを検索して再生するインターフェイスを提供できます。

ここではAndroidデバイスで内蔵スピーカーまたは接続されたヘッドフォンで音楽を再生するアプリを既に作っていると想定します。Autoデバイス内であなたのコンテンツを検索してカーステレオで再生するためにアプリを拡張する方法を紹介します。

Audio Serviceを提供する

AudioアプリはAndroid Auto上のダッシュボードデバイスを直接コントロールしません。ユーザーがAndroidモバイルデバイスをダッシュボードシステムに接続すると、Android Autoはmanifestのエントリーを通じてオーディオサービスを提供できるアプリを探し出します。ダッシュボードシステムは音楽の提供元としてユーザーがアプリのサービスを選択できるように、あなたのアプリのlauncher iconを表示します。もしユーザーがあなたのアプリを実行すると、Autoデバイスは利用可能なコンテンツをあなたのアプリに問い合わせ、コンテンツアイテムをユーザーに表示し、あなたのアプリに再生、一時停止、次のトラックへスキップなどのアクションのコントロールプレイバックを問い合わせます。

Auto向けのオーディオコンテンツを提供できるようにするために以下のことが必要です。

・アプリのmanifestに以下を記載する
○アプリが音声のコンテンツをAutoデバイスに提供できると宣言する。
○閲覧可能なリストを提供するサービスを定義する。

・オーディオトラックリストの情報を提供するMediaBrowserServiceを継承したサービスを構築する。

MediaSessionオブジェクトを登録し、音楽再生コントロールを可能にするMediaSession.Callbackオブジェクトを実装する。

Manifestを設定する

ユーザーがAutoが動くダッシュボードシステムにAndroidモバイルデバイスを接続したら、システムはAutoデバイスに対応したサービスとapp manifestで指定されているインストールされたアプリとそのアクセス方法のリストを要求します。

この章ではアプリのmanifestでAutoデバイス向けのオーディオサービスをサポートしていると指定する方法とダッシュボードシステムとアプリを接続する方法を紹介します。

Auto オーディオサポートを宣言する

Autoの機能をサポートしていることを示すために以下のManifestのエントリーを使用します。

<application>
...
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
...
<application>

このmanifestのエントリーは2つ目のどのAutoの機能をサポートするかを宣言したXMLファイルを参照します。
Auto向けのオーディオをサポートするためにリソースディレクトリ、 res/xml/ に 下記の内容が入ったautomotive_app_desc.xmlを追加します。

<automotiveApp>
<uses name="media"/>
</automotiveApp>

Autoデバイスのための機能を宣言するより詳細についてはAutoを始めるを見てください。

media browser serviceを宣言する

Autoデバイスは音楽トラックリストをブラウジングするためのサービスに接続されることを期待しています。ダッシュボードシステムがサービスを発見してあなたのアプリに接続できるようにするにはmanifestでこのサービスを宣言します。

以下はmanifest内でブラウザーサービスを宣言するコード例です。

<application>
...
<service android:name=".MyMediaBrowserService"
android:exported="true">
<intent-filter>
<action android:name=
"android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
...
<application>

オーディオトラックをブラウジングするためにアプリのサービスはMediaBrowserServiceを継承して作る必要があります。このサービスで実装すべきことはBrowser Serviceを構築するの章で説明されています。
メモ:Auto以外の他のクライアントがあなたのアプリのブラウザーサービスと接続することも出来ます。これらのメディアクライアントは携帯端末内の他のアプリかも知れませんし、他のリモートクライアントかも知れません。

Notification iconを指定する

Autoのユーザーインターフェイスはユーザーが操作している時にオーディオアプリについてのNotificationを表示することがあります。例えば、もしユーザーがナビアプリを実行している時に、曲が終了し新しい曲が開始されたらユーザーに変更を知らせるためにNotificationでアプリのアイコンを表示します。
アプリアイコンの代わりに通知で使うアイコンをManifestに定義して指定することが出来ます。

<application>
...
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="@drawable/ic_notification" />
...
</application>

メモ:アイコンは透明度を提供する必要があります。それにより、アイコンの背景はアプリのprimary colorで塗りつぶされます。

Browser Serviceを構築する

Autoデバイスはアプリのmanifestで記載したMediaBrowserServiceの実装と接続することであなたのアプリと対話します。このサービスはデバイスにあなたのアプリがどのようなコンテンツを持っているかを探しださせます。
接続されたAutoデバイスはあなたのアプリが提供するMediaSessionに接続するためにmedia browser serviceに問い合わせたりコンテンツの再生制御も行います。

MediaBrowserServiceクラスを継承してmedia browser serviceを作成します。接続されたAutoデバイスはあなたのサービスに接続して以下のことを行います。

・コンテンツの階層をブラウジングするためにメニューを表示する。
・オーディオ再生を制御するために、アプリのMediaSessionオブジェクトのTokenを取得する。

Media browser sevice のワークフロー

1. ユーザーがAutoデバイスと接続してあなたのアプリのaudio servicesが必要となった時、ダッシュボードシステムはあなたのアプリのMedia browser serviceに接続します。onCreate()メソッドでMediaSessionオブジェクトとコールバックオブジェクトを作成し登録する必要があります。

2.Autoデバイスはbrowser serviceのonGetRoot()メソッドを呼びあなたのコンテンツ階層の最上位にあるノードを取得します。この呼出しで取得されたノードはメニュー項目としては使われず、最上位のメニュー項目として表示される子ノードを取り戻すためだけに使われます。

3.AutoはonLoadChildren()ルートノードの子要素を取得するためにonLoadChildren()を実行し、この情報をユーザーにメニューとして表示します。

4.もし、ユーザーがサブメニューを選択したらAUTOは選択されたメニューアイテムの子要素を取得するために再度onLoadChildren()を実行します。

5.もし、ユーザーが再生を開始したらAutoはアクションを行うために対応したmedia sessionのコールバックメソッドを実行します。より詳細は「再生コントロールを有効にする」の章を参照してください。

コンテンツの階層を作る

Autoデバイスはオーディオクライアントとして、あなたのアプリがどんな利用可能コンテンツを持っているかを探し出すためにあなたのアプリのMediaBrowserServiceを呼びます。Browser serviceではonGetRoot()onLoadChildren()の2つのメソッドを実装する必要があります。

MediaBrowser.MediaIteオブジェクトによって各コンテンツ階層のノードが表示されます。それらのオブジェクトはそれぞれ一意なStringのIDで特定されます。クライアントはそれらのID文字列を不透明なトークンとして取り扱います。
クライアントがサブメニューをブラウズしようとした場合やコンテンツアイテムを再生するとき、このIDトークンが渡されます。あなたのアプリはIDトークンと関連するメニューノードやコンテンツアイテムを結びつける役割を持ちます。

メモ:あなたはクライアントがどのようなクエリを作ったかにより異なるコンテンツの階層を提供することを熟考する必要があります。特にAutoアプリケーションはメニューに表示できる量がとても限られています。これはドライバーの意識を阻害せず、音声コマンドによる操作を通じて簡単な操作を提供するという目的があります。Autoユーザーエクスペリエンスの制限についてより詳しい情報はAuto Media Appsガイドラインを呼んでください。

onGetRoot()の実装では、メニュー階層のルートノードについての情報を返します。このルートノードはブラウズする階層のトップアイテムの親となります。このメソッドには呼び出したクライアントの情報が渡されます。この情報を使ってクライアントがどのコンテンツにアクセスできるかを切り分けることが出来ます。例えば、もし、許可されたクライアントのみにあなたのコンテンツを制限したいなら、渡されるClientPackageNameであなたのホワイトリストと比較することが出来ます。もし、呼び出し元が許可したパッケージでなかったらnullを返すことでコンテンツへのアクセスを拒否できます。

一般的なonGetRoot()の実装は以下のとおりです。

@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
Bundle rootHints) {

// 様々な勝手アプリに対してあなたのコンテンツへのアクセスを拒否することを確実にするために
// 出処を調べる必要があります。
if (!PackageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
// もし、信用できないパッケージからリクエストを受けていた場合nullを返します。
// 他のメディアブラウジングメソッドはこれ以上呼ばれません。
LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package "
+ clientPackageName);
return null;
}
if (ANDROID_AUTO_PACKAGE_NAME.equals(clientPackageName)) {
// 任意:もし、あなたのアプリが広告や音楽ライブラリーなどを自動車に接続時だけ
//別に対応する必要があるならここで行います。
}
return new BrowserRoot(MEDIA_ID_ROOT, null);
}

AutoデバイスクライアントはルートノードオブジェクトのonLoadChildren()を呼んで子階層を取得しトップレベルメニューを作ります。
クライアントは他の子ノードに対しても同じメソッドを呼びサブメニューを作ります。以下のコード例はシンプルなonLoadChildren()メソッドの実装例です。

@Override
public void onLoadChildren(final String parentMediaId,
final Result<List<MediaItem>> result) {

// この例では音楽カタログが既に読み込まれているかキャッシュされているものとします。

List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();

// ルートメニューかどうかチェックする。
if (MEDIA_BROWSER_ROOT.equals(parentMediaId)) {

// トップレベルオブジェクトのMediaItemオブジェクトを作成し、
// <result>リストに入れます。
} else {

// どのサブメニューにいるかを知るために、渡されたparentMediaIdを調べてください。
// そして、子メニューを<result>リストの中に入れてください。
}
}

再生コントロールを有効にする

Autoデバイスは再生コントロールコマンドをオーディオサービスを提供するアプリに渡すためにMediaSessionオブジェクトを使用します。あなたのオーディオアプリはダッシュボードデバイスに渡すためにこのオブジェクトのインスタンスを作る必要があります。またオーディオ再生のリモートコントロールを有効にするためにコールバックメソッドを実装する必要があります。

Media sessionを登録する

Autoデバイスはあなたのアプリをオーディオサービスとして使用するためにMediaSessionを取得します。
Autoデバイスはユーザーがあなたのアプリに要求した再生コマンドを送るためにこのsessionオブジェクトを使用します。

Browser serviceを初期化時にsetSessionToken()メソッドを呼ぶことでMediaBrowserServiceを使用してsessionオブジェクトを登録します。これにより、AutoデバイスなどのクライアントはあなたのBrwoser serviceのgetSessionToken()メソッドによりオブジェクトを検索できるようになります。

Browser serviceのonCreate()メソッドでMediaSessionを作ります。
そして、MediaSessionに問い合わせを行いトークンを取得しBrowser serviceに登録することが出来ます。

public void onCreate() {
super.onCreate();

...
// あたらしいMediaSessionを開始する
MediaSession mSession = new MediaSession(this, "session tag");
setSessionToken(mSession.getSessionToken());

// 再生リクエストを取り扱うためにMediaSession.Callbackを
// 実装したコールバックオブジェクトを登録する
mSession.setCallback(new MyMediaSessionCallback());

...

media sessionオブジェクトを作るとき、再生コントロールを取り扱うために使うコールバックオブジェクトをセットします。アプリでMediaSession.Callbackクラスを実装してコールバックオブジェクトを作ります。次の章ではこのオブジェクトの実装方法について紹介します。

再生コマンドを実装する

Autoデバイスがあなたのアプリにオーディオトラックの再生を要求する時、あなたのMedia browse serviceから得たMediaSessionオブジェクトのMediaSession.Callbackクラスを使います。Autoユーザーがコンテンツを再生したり、一時停止や次のトラックへ移るなど再生を制御したい時はAutoはコールバックオブジェクトのメソッドを1つ実行します。

コンテンツ再生を取り扱うために、アプリはMediaSession.Callback抽象クラスを継承して、アプリがサポートするメソッドの実装を行う必要があります。もっとも重要なコールバックメソッドは以下のとおりです。
onPlay()
ユーザーが特定のアイテムを選択せずに再生を選んだ場合に実行されます。アプリは標準のコンテンツを再生します。もし、onPause()により一時停止している場合は、アプリは再生を再開しないといけません。
onPlayFromMediaId()
ユーザーが特定のアイテムを指定して再生を選んだ場合に実行されます。このメソッドにはコンテンツ階層内のアイテムに関連したアイテムのmedia IDが渡されます。
onPlayFromSearch()
検索結果からの再生をユーザーが選択した場合に実行されます。アプリは検索文字列に基づいて適切にコンテンツを選択します。
onPause()
再生を一時停止します。
onSkipToNext()
次のアイテムまでスキップします。
onSkipToPrevious()
前のアイテムまでスキップします。
onStop()
再生を停止します。

あなたのアプリは希望する機能をOverrideする必要があります。アプリがサポートしていない機能については実装しない場合がよくあります。例えば、アプリが生放送のストリーミング(スポーツ放送など)を再生する場合、skip to next機能は持たないでしょう。このような場合は単にonSkipToNext()の標準実装を使用することが出来ます。

コンテンツを再生するリクエストを受け取ったら、Auto以外の場合(デバイスのスピーカーやヘッドフォンを繋いで聴くときなど)と同じ方法でオーディオを再生してください。オーディオコンテンツは車のスピーカーで再生するために自動的にダッシュボードシステムに送られます。

スマートフォンがAutoデバイスと接続されている時(MediaPlayerExoPlayerを使う方法などの)オーディオコンテンツを再生するためのより詳細はMedia PlaybackManaging Audio PlaybackExoPlayerを見てください。



Except as noted, this content is licensed under Creative Commons Attribution 2.5. For details and restrictions, see the Content License.

前:Autoを始める 次:Autoのためのメッセージ

関連キーワード

[][Android][Java][モバイル][IT][翻訳]

コメントを投稿する

名前URI
コメント