使用 MediaLibraryService 提供內容

媒體應用程式通常會包含媒體項目集合,並以階層方式排序。例如專輯中的歌曲,或是播放清單中的電視劇集。這個媒體項目的階層稱為媒體庫。

以階層排列的媒體內容示例
圖 1:構成媒體庫的媒體項目階層範例。

MediaLibraryService 提供標準化 API,可用於提供及存取媒體資料庫。舉例來說,這非常實用,像是在媒體應用程式新增對 Android Auto 的支援時,為媒體庫提供能安全駕駛的 UI。

建構 MediaLibraryService

實作 MediaLibraryService實作 MediaSessionService 類似,但在 onGetSession() 方法中,您應傳回 MediaLibrarySession,而非 MediaSession

Kotlin

class PlaybackService : MediaLibraryService() {
  var mediaLibrarySession: MediaLibrarySession? = null
  var callback: MediaLibrarySession.Callback = object : MediaLibrarySession.Callback {...}

  // If desired, validate the controller before returning the media library session
  override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession? =
    mediaLibrarySession

  // Create your player and media library session in the onCreate lifecycle event
  override fun onCreate() {
    super.onCreate()
    val player = ExoPlayer.Builder(this).build()
    mediaLibrarySession = MediaLibrarySession.Builder(this, player, callback).build()
  }

  // Remember to release the player and media library session in onDestroy
  override fun onDestroy() {
    mediaLibrarySession?.run { 
      player.release()
      release()
      mediaLibrarySession = null
    }
    super.onDestroy()
  }
}

Java

class PlaybackService extends MediaLibraryService {
  MediaLibrarySession mediaLibrarySession = null;
  MediaLibrarySession.Callback callback = new MediaLibrarySession.Callback() {...};

  @Override
  public MediaLibrarySession onGetSession(MediaSession.ControllerInfo controllerInfo) {
    // If desired, validate the controller before returning the media library session
    return mediaLibrarySession;
  }

  // Create your player and media library session in the onCreate lifecycle event
  @Override
  public void onCreate() {
    super.onCreate();
    ExoPlayer player = new ExoPlayer.Builder(this).build();
    mediaLibrarySession = new MediaLibrarySession.Builder(this, player, callback).build();
  }

  // Remember to release the player and media library session in onDestroy
  @Override
  public void onDestroy() {
    if (mediaLibrarySession != null) {
      mediaLibrarySession.getPlayer().release();
      mediaLibrarySession.release();
      mediaLibrarySession = null;
    }
    super.onDestroy();
  }
}

請記得在資訊清單檔案中宣告 Service 和必要權限:

<service
    android:name=".PlaybackService"
    android:foregroundServiceType="mediaPlayback"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaSessionService"/>
    </intent-filter>
</service>

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- For targetSdk 34+ -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

使用 MediaLibrarySession

MediaLibraryService API 會預期媒體庫以樹狀結構建構,其中包含單一根節點和可播放或進一步瀏覽的子節點。

MediaLibrarySession 會擴充 MediaSession API,用於新增內容瀏覽 API。與 MediaSession 回呼相比,MediaLibrarySession 回呼會新增下列方法:

  • onGetLibraryRoot() 用於用戶端要求內容樹狀結構的根目錄 MediaItem
  • onGetChildren() 用於用戶端要求內容樹狀結構中 MediaItem 的子項
  • onGetSearchResult() 用於當用戶端針對特定查詢要求內容樹狀結構中的搜尋結果時

相關的回呼方法會包含 LibraryParams 物件,其中包含關於用戶端應用程式感興趣的內容樹狀結構類型的額外信號。