媒體會話與它所管理的播放器共存。您應(yīng)該在擁有媒體會話及其關(guān)聯(lián)播放器的活動或服務(wù)的onCreate()方法中創(chuàng)建并初始化一個媒體會話。
注意:編寫媒體應(yīng)用程序的最佳實(shí)踐是使用media-compat庫。在本頁中,術(shù)語“媒體會話”指的是MediaSessionCompat的實(shí)例,而“媒體控制器”指的是MediaControllerCompat的實(shí)例。
初始化媒體會話media session
新創(chuàng)建的媒體會話沒有功能。您必須通過執(zhí)行以下步驟來初始化會話:
- 設(shè)置標(biāo)志,以便媒體會話可以接收來自媒體控制器和媒體按鈕的回調(diào)。
- 創(chuàng)建并初始化一個
PlaybackStateCompat實(shí)例,并將其分配給會話?;胤艩顟B(tài)會在整個會話期間發(fā)生變化,因此我們建議緩存PlaybackStateCompat.Builder以便重用。 - 創(chuàng)建
MediaSessionCompat.CallBack實(shí)例并將其分配給會話(更多關(guān)于回調(diào)的內(nèi)容見下文)。
您應(yīng)該在擁有會話的活動或服務(wù)的onCreate()方法中創(chuàng)建和初始化一個媒體會話。
為了讓媒體按鈕在應(yīng)用程序新初始化(或停止)時正常工作,其PlaybackState必須包含與媒體按鈕發(fā)送的意圖匹配的play操作。這就是為什么ACTION_PLAY在初始化期間被分配給會話狀態(tài)。有關(guān)更多信息,請參見對媒體按鈕的響應(yīng)。
維護(hù)播放狀態(tài)和元數(shù)據(jù)
有兩個類表示媒體會話的狀態(tài)。
PlaybackStateCompat類描述了播放器的當(dāng)前操作狀態(tài)。這包括:
- 傳輸狀態(tài)(播放器是否在玩/暫停/緩沖,等等???a target="_blank" rel="nofollow">getState())
- 適用時的錯誤代碼和可選錯誤消息。(參見下面的getErrorCode()和讀取狀態(tài)和錯誤)
- 播放器的位置
- 可以在當(dāng)前狀態(tài)下處理的有效控制器操作
MediaMetadataCompat類描述正在播放的材料:
- 藝術(shù)家、專輯和歌曲的名字
- 跟蹤持續(xù)時間
- 相冊藝術(shù)品顯示在鎖屏上。圖像是一個最大大小為320x320dp的位圖(如果較大,則按比例縮小)。
-
contenturi的一個實(shí)例,它指向一個更大版本的藝術(shù)品
播放器狀態(tài)和元數(shù)據(jù)可以在媒體會話的生命周期中發(fā)生變化。每當(dāng)狀態(tài)或元數(shù)據(jù)發(fā)生更改時,您必須為每個類使用相應(yīng)的生成器,即PlaybackStateCompat.Builder()或MediaMetadataCompat.Builder(),然后通過調(diào)用setPlaybackState()或setMetaData()將新實(shí)例傳遞給媒體會話。為了減少這些頻繁操作的總內(nèi)存消耗,最好一次性創(chuàng)建構(gòu)建器,并在會話的整個生命周期中重用它們。
狀態(tài)和錯誤
注意,PlaybackState是一個對象,它包含會話播放狀態(tài)的單獨(dú)值(getState()),必要時還包含一個關(guān)聯(lián)的錯誤代碼(getErrorCode())。錯誤可以是致命的,也可以是非致命的:
每當(dāng)播放中斷時,您應(yīng)該生成一個致命錯誤:將傳輸狀態(tài)設(shè)置為STATE_ERROR,并指定與setErrorMessage(int, CharSequence)相關(guān)聯(lián)的錯誤。只要播放被錯誤阻塞,PlaybackState就應(yīng)該繼續(xù)報(bào)告STATE_ERROR和錯誤。
當(dāng)您的應(yīng)用程序不能處理請求,但可以繼續(xù)運(yùn)行時,就會出現(xiàn)非致命錯誤:傳輸保持“正常”狀態(tài)(比如STATE_PLAYING),但PlaybackState保存了一個錯誤代碼。例如,如果最后一首歌正在播放,用戶請求跳轉(zhuǎn)到下一首歌,播放可以繼續(xù),但是您應(yīng)該使用錯誤代碼ERROR_CODE_END_OF_QUEUE創(chuàng)建一個新的PlaybackState,然后調(diào)用setPlaybackState()。連接到會話的媒體控制器將接收回調(diào)onPlaybackStateChanged()并向用戶解釋發(fā)生了什么。非致命錯誤應(yīng)該僅在發(fā)生時報(bào)告一次。下次會話更新時,PlaybackState不會再次設(shè)置相同的非致命錯誤(除非在響應(yīng)新請求時發(fā)生錯誤)。
媒體會話鎖定屏幕
從Android 4.0 (API level 14)開始,系統(tǒng)可以訪問媒體會話的回放狀態(tài)和元數(shù)據(jù)。這是鎖定屏幕如何顯示媒體控件和藝術(shù)品。這種行為會因Android版本的不同而有所不同。
專輯作品
在Android 4.0 (API level 14)及更高版本中,鎖定屏幕的背景會顯示出你的專輯封面——但前提是媒體會話元數(shù)據(jù)包含背景位圖。
傳輸控制
在Android 4.0 (API級別14)到Android 4.4 (API級別19)中,當(dāng)媒體會話處于活動狀態(tài),且媒體會話元數(shù)據(jù)包含背景位圖時,鎖屏屏幕會自動顯示傳輸控件。
在Android 5.0 (API level 21)或更高版本中,系統(tǒng)不提供鎖定屏幕上的傳輸控制。相反,您應(yīng)該使用MediaStyle通知來顯示傳輸控件。
添加自定義操作
您可以使用addCustomAction()添加自定義操作。例如,添加一個控件來實(shí)現(xiàn)一個點(diǎn)贊的動作:
stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
CUSTOM_ACTION_THUMBS_UP, mResources.getString(R.string.thumbs_up), thumbsUpIcon)
.setExtras(customActionExtras)
.build());
有關(guān)完整示例,請參閱Universal Music Player。
您可以使用onCustomAction()來響應(yīng)該操作。
@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
if (CUSTOM_ACTION_THUMBS_UP.equals(action)) {
...
}
}
這里也可以參閱Universal Music Player
媒體會話回調(diào)
主媒體會話回調(diào)方法是onPlay()、onPause()和onStop()。這是您添加控制播放器的代碼的地方。
由于在運(yùn)行時實(shí)例化并設(shè)置會話回調(diào)(在onCreate()中),應(yīng)用程序可以定義使用不同播放器的替代回調(diào),并根據(jù)設(shè)備和/或系統(tǒng)級別選擇適當(dāng)?shù)幕卣{(diào)/播放器組合。你可以在不改變應(yīng)用程序其余部分的情況下改變播放器。例如,你可以在Android 4.1 (API level 16)或更高版本上使用ExoPlayer,在早期的系統(tǒng)上使用MediaPlayer。
除了控制播放器和管理媒體會話狀態(tài)轉(zhuǎn)換外,回調(diào)還啟用和禁用應(yīng)用程序的特性,并控制它與其他應(yīng)用程序和設(shè)備硬件交互的方式。(參見控制音頻輸出)。
媒體會話回調(diào)方法的實(shí)現(xiàn)取決于應(yīng)用程序的結(jié)構(gòu)。請參閱分別描述如何在音頻應(yīng)用程序和視頻應(yīng)用程序中使用回調(diào)的頁面,描述每種應(yīng)用程序的回調(diào)應(yīng)該如何實(shí)現(xiàn)。