讓Android顯示正在播放卡片

2018-08-02 17:59 更新

編寫:huanglizhuo - 原文:http://developer.android.com/training/tv/playback/now-playing.html

TV應(yīng)用允許用戶在使用其他應(yīng)用時(shí)后臺(tái)播放音樂或其他媒體。如果我們的應(yīng)用程序允許后臺(tái),它必須要為用戶提供返回該應(yīng)用暫停音樂或切換到一個(gè)新的歌曲的方法。 Android框架允許TV應(yīng)用通過在主屏幕上顯示正在播放卡做到這一點(diǎn)。

正在播放卡片是系統(tǒng)的組建,它可以在推薦的行上顯示正在播放的媒體會(huì)話它包括了媒體元數(shù)據(jù),如專輯封面,標(biāo)題和應(yīng)用程序圖標(biāo)。當(dāng)用戶選擇它,系統(tǒng)將打開擁有該會(huì)話的應(yīng)用程序。

這節(jié)課將演示如何使用 MediaSession 類實(shí)現(xiàn)正在播放卡片。

開啟媒體會(huì)話

一個(gè)播放應(yīng)用可以作為 activity 或者 service 運(yùn)行。 service 是當(dāng) activity 結(jié)束時(shí)依然可以后臺(tái)播放的。在這節(jié)討論中,媒體播放應(yīng)用是假設(shè)在 MediaBrowserService 下運(yùn)行的。

在service的onCreate())方法中創(chuàng)建一個(gè)新的 MediaSession ),設(shè)置適當(dāng)?shù)幕卣{(diào)函數(shù)和標(biāo)志,并設(shè)置 MediaBrowserService 令牌。

mSession = new MediaSession(this, "MusicService");
mSession.setCallback(new MediaSessionCallback());
mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
        MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);

// for the MediaBrowserService
setSessionToken(mSession.getSessionToken());

注意:正在播放卡片只有在媒體會(huì)話設(shè)置了FLAG_HANDLES_TRANSPORT_CONTROLS標(biāo)志時(shí)在可以顯示。

顯示正在播放卡片

如果會(huì)話是系統(tǒng)最高優(yōu)先級(jí)的會(huì)話那么正在播放卡片將在setActivity(true))調(diào)用后顯示。同時(shí)我們的應(yīng)用必須像在Managing Audio Focus一節(jié)中那樣請(qǐng)求音頻焦點(diǎn)。

private void handlePlayRequest() {

    tryToGetAudioFocus();

    if (!mSession.isActive()) {
        mSession.setActive(true);
    }
...

如果另一個(gè)應(yīng)用發(fā)起媒體播放請(qǐng)求并調(diào)用setActivity(false))后這個(gè)卡片將從主屏上移除。

更新播放狀態(tài)

正如任何媒體的應(yīng)用程序,在 MediaSession 中更新播放狀態(tài),使卡片可以顯示當(dāng)前的元數(shù)據(jù),如在下面的例子:

private void updatePlaybackState() {
    long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
    if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
        position = mMediaPlayer.getCurrentPosition();
    }
    PlaybackState.Builder stateBuilder = new PlaybackState.Builder()
            .setActions(getAvailableActions());
    stateBuilder.setState(mState, position, 1.0f);
    mSession.setPlaybackState(stateBuilder.build());
}
private long getAvailableActions() {
    long actions = PlaybackState.ACTION_PLAY |
            PlaybackState.ACTION_PLAY_FROM_MEDIA_ID |
            PlaybackState.ACTION_PLAY_FROM_SEARCH;
    if (mPlayingQueue == null || mPlayingQueue.isEmpty()) {
        return actions;
    }
    if (mState == PlaybackState.STATE_PLAYING) {
        actions |= PlaybackState.ACTION_PAUSE;
    }
    if (mCurrentIndexOnQueue > 0) {
        actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
    }
    if (mCurrentIndexOnQueue < mPlayingQueue.size() - 1) {
        actions |= PlaybackState.ACTION_SKIP_TO_NEXT;
    }
    return actions;
}

顯示媒體元數(shù)據(jù)

為當(dāng)前正在播放通過setMetadata())方法設(shè)置 MediaMetadata 。.這個(gè)方法可以讓我們?yōu)檎诓シ趴ㄌ峁┯嘘P(guān)軌道,如標(biāo)題,副標(biāo)題,和各種圖標(biāo)等信息。下面的例子假設(shè)我們的播放數(shù)據(jù)存儲(chǔ)在自定義的MediaData類中。

private void updateMetadata(MediaData myData) {
    MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder();
    // To provide most control over how an item is displayed set the
    // display fields in the metadata
    metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE,
            myData.displayTitle);
    metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE,
            myData.displaySubtitle);
    metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI,
            myData.artUri);
    // And at minimum the title and artist for legacy support
    metadataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE,
            myData.title);
    metadataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST,
            myData.artist);
    // A small bitmap for the artwork is also recommended
    metadataBuilder.putString(MediaMetadata.METADATA_KEY_ART,
            myData.artBitmap);
    // Add any other fields you have for your data as well
    mSession.setMetadata(metadataBuilder.build());
}

響應(yīng)用戶的動(dòng)作

當(dāng)用戶選擇正在播放卡片時(shí),系統(tǒng)打開應(yīng)用并擁有會(huì)話。如果我們的應(yīng)用在setSessionActivity())有PendingIntent要傳遞,系統(tǒng)將會(huì)像下面演示的那樣開啟activity。如果不是,則系統(tǒng)默認(rèn)的Intent打開。您指定的活動(dòng)必須提供播放控制,允許用戶暫?;蛲V共シ?。

Intent intent = new Intent(mContext, MyActivity.class);
    PendingIntent pi = PendingIntent.getActivity(context, 99 /*request code*/,
            intent, PendingIntent.FLAG_UPDATE_CURRENT);
    mSession.setSessionActivity(pi);


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)