1page.title=再生中カードを表示する
2page.tags=tv, mediasession
3
4trainingnavtop=true
5
6@jd:body
7
8<div id="tb-wrapper">
9<div id="tb">
10  <h2>学習の目的</h2>
11  <ol>
12    <li><a href="#session">Media Session を起動する</a></li>
13    <li><a href="#card">再生中カードを表示する</a></li>
14    <li><a href="#state">再生ステータスをアップデートする</a></li>
15    <li><a href="#respond">ユーザー アクションを処理する</a></li>
16  </ol>
17
18</div>
19</div>
20
21<p>TV アプリでは、ユーザーが他のアプリを使用中にバックグラウンドで音楽やその他のメディアを再生できる場合があります。このタイプのアプリの場合、アプリに戻って音楽を一時停止したり、新しい曲に切り替えたりする方法をユーザーに提供する必要があります。Android のフレームワークでは、ホーム スクリーン上の推奨する行に [<em>再生中</em>] カードを表示することで、 TV アプリで上記の操作を行えるようになります。</p>
22
23<p>[再生中] カードは、アクティブなメディア セッションのホーム スクリーンの推奨する行に表示されるシステム アーティファクトです。アルバム アート、タイトル、アプリのアイコンなど、メディアのメタデータが含まれます。ユーザーが選択すると、システムはセッション中のアプリを開きます。</p>
24
25<p>このレッスンでは、{@link android.media.session.MediaSession} クラスを使用して [再生中] カードを実装する方法を説明します。</p>
26
27<h2 id="session">Media Session を起動する</h2>
28
29<p>再生アプリは<a href="{@docRoot}guide/components/activities">アクティビティ</a>か<a href="{@docRoot}guide/components/services">サービス</a>として実行できます。サービスは、サービスを開始したアクティビティが破棄された後もメディアの再生を継続できるため、バックグラウンド再生時に必要となります。ここでは、メディア再生アプリが {@link android.service.media.MediaBrowserService} で実行されているものとします。</p>
30
31<p>ご使用中のサービスの{@link android.service.media.MediaBrowserService#onCreate() onCreate()}メソッドで、{@link android.media.session.MediaSession#MediaSession(android.content.Context, java.lang.String) MediaSession} を新規作成し、メディア アプリへの適切なコールバックとフラグを設定して、{@link android.service.media.MediaBrowserService} のセッション トークンを設定します。</p>
32
33<pre>
34mSession = new MediaSession(this, "MusicService");
35mSession.setCallback(new MediaSessionCallback());
36mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
37        MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
38
39// for the MediaBrowserService
40setSessionToken(mSession.getSessionToken());
41</pre>
42
43<p class="note"><strong>注意:</strong>[再生中] カードは、{@link android.media.session.MediaSession#FLAG_HANDLES_TRANSPORT_CONTROLS} フラグが設定されたメディア セッションでのみ表示されます。</p>
44
45<h2 id="card">再生中カードを表示する</h2>
46
47<p>[再生中] カードは、セッションがシステム内で最も優先度の高い場合に、{@link android.media.session.MediaSession#setActive(boolean) setActive(true)} を呼び出した後に表示されます。また、<a href="{@docRoot}training/managing-audio/audio-focus">オーディオ フォーカスを管理する</a>で説明したように、アプリからオーディオ フォーカスをリクエストする必要があります。</p>
48
49<pre>
50private void handlePlayRequest() {
51
52    tryToGetAudioFocus();
53
54    if (!mSession.isActive()) {
55        mSession.setActive(true);
56    }
57...
58</pre>
59
60<p>{@link android.media.session.MediaSession#setActive(boolean) setActive(false)} の呼び出し時や別のアプリがメディアの再生を開始した場合に、カードはホーム スクリーンから削除されます。再生が一時停止された後、通常は 5~30 分間、カードを表示したままにして、その後カードをホーム スクリーンから削除することもできiます。</p>
61
62<h2 id="state">再生ステータスをアップデートする</h2>
63
64<p>どのメディア アプリの場合でも、次の例のように現在のメタデータを表示するよう、{@link android.media.session.MediaSession} で再生ステータスをアップデートするようにします。</p>
65
66<pre>
67private void updatePlaybackState() {
68    long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
69    if (mMediaPlayer != null &amp;&amp; mMediaPlayer.isPlaying()) {
70        position = mMediaPlayer.getCurrentPosition();
71    }
72    PlaybackState.Builder stateBuilder = new PlaybackState.Builder()
73            .setActions(getAvailableActions());
74    stateBuilder.setState(mState, position, 1.0f);
75    mSession.setPlaybackState(stateBuilder.build());
76}
77private long getAvailableActions() {
78    long actions = PlaybackState.ACTION_PLAY |
79            PlaybackState.ACTION_PLAY_FROM_MEDIA_ID |
80            PlaybackState.ACTION_PLAY_FROM_SEARCH;
81    if (mPlayingQueue == null || mPlayingQueue.isEmpty()) {
82        return actions;
83    }
84    if (mState == PlaybackState.STATE_PLAYING) {
85        actions |= PlaybackState.ACTION_PAUSE;
86    }
87    if (mCurrentIndexOnQueue &gt; 0) {
88        actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
89    }
90    if (mCurrentIndexOnQueue &lt; mPlayingQueue.size() - 1) {
91        actions |= PlaybackState.ACTION_SKIP_TO_NEXT;
92    }
93    return actions;
94}
95</pre>
96
97<h2 id="metadata">メディアのメタデータを表示する</h2>
98
99<p>トラックが現在再生中の場合は、{@link android.media.session.MediaSession#setMetadata(android.media.MediaMetadata) setMetadata()} メソッドを使用して{@link android.media.MediaMetadata} を設定します。メディア セッション オブジェクトのこのメソッドを使用すると、タイトル、サブタイトル、さまざまなアイコンなど、トラックに関する情報を [再生中] カードに表示することができます。次の例は、トラック データがカスタムデータ クラスの {@code MediaData} に格納されている場合です。</p>
100
101<pre>
102private void updateMetadata(MediaData myData) {
103    MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder();
104    // To provide most control over how an item is displayed set the
105    // display fields in the metadata
106    metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE,
107            myData.displayTitle);
108    metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE,
109            myData.displaySubtitle);
110    metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI,
111            myData.artUri);
112    // And at minimum the title and artist for legacy support
113    metadataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE,
114            myData.title);
115    metadataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST,
116            myData.artist);
117    // A small bitmap for the artwork is also recommended
118    metadataBuilder.putString(MediaMetadata.METADATA_KEY_ART,
119            myData.artBitmap);
120    // Add any other fields you have for your data as well
121    mSession.setMetadata(metadataBuilder.build());
122}
123</pre>
124
125<h2 id="respond">ユーザー アクションを処理する</h2>
126
127<p>ユーザーが [再生中] カード選択すると、システムはセッション中のアプリを開きます。TV アプリが {@link android.app.PendingIntent} を{@link android.media.session.MediaSession#setSessionActivity(android.app.PendingIntent) setSessionActivity()}に渡した場合は、指定したアクティビティをシステムが次のように開始します。それ以外の場合は、デフォルトのシステム インテントが開きます。指定対象のアクティビティでは、ユーザーに再生の一時停止または停止(再生コントロール)機能を提供する必要があります。</p>
128
129<pre>
130Intent intent = new Intent(mContext, MyActivity.class);
131    PendingIntent pi = PendingIntent.getActivity(context, 99 /*request code*/,
132            intent, PendingIntent.FLAG_UPDATE_CURRENT);
133    mSession.setSessionActivity(pi);
134</pre>
135