یک جلسه رسانه ای اجرا کنید

وقتی برنامه شما در حال آماده شدن برای پخش رسانه است، یک MediaSession ایجاد کنید. قطعه کد زیر نمونه‌ای از نحوه تنظیم callback و flag های مناسب است:

کاتلین

session = MediaSession(this, "MusicService").apply {
    setCallback(MediaSessionCallback())
    setFlags(
        MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
    )
}

جاوا

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

شروع یک جلسه رسانه‌ای

حتماً هنگام شروع پخش، setActive(true) نیز فراخوانی کنید. برنامه شما همچنین باید فوکوس صوتی را درخواست کند، همانطور که در مدیریت فوکوس صوتی توضیح داده شده است. این مراحل در مثال زیر نشان داده شده است:

کاتلین

fun handlePlayRequest() {
    tryToGetAudioFocus()

    if (!session.isActive) {
        session.isActive = true
    }
    // ...
}

جاوا

private void handlePlayRequest() {

    tryToGetAudioFocus();

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

به‌روزرسانی وضعیت پخش

وضعیت پخش را در MediaSession به‌روزرسانی کنید تا وضعیت رسانه فعلی را منعکس کند:

کاتلین

private fun updatePlaybackState() {
    val position: Long =
        mediaPlayer
            ?.takeIf { it.isPlaying }
            ?.currentPosition?.toLong()
            ?: PlaybackState.PLAYBACK_POSITION_UNKNOWN

    val stateBuilder = PlaybackState.Builder()
        .setActions(getAvailableActions()).apply {
            setState(mState, position, 1.0f)
        }
    session.setPlaybackState(stateBuilder.build())
}

private fun getAvailableActions(): Long {
    var actions = (
        PlaybackState.ACTION_PLAY_PAUSE
            or PlaybackState.ACTION_PLAY_FROM_MEDIA_ID
            or PlaybackState.ACTION_PLAY_FROM_SEARCH
        )

    playingQueue?.takeIf { it.isNotEmpty() }?.apply {
        actions = if (mState == PlaybackState.STATE_PLAYING) {
            actions or PlaybackState.ACTION_PAUSE
        } else {
            actions or PlaybackState.ACTION_PLAY
        }
        if (currentIndexOnQueue > 0) {
            actions = actions or PlaybackState.ACTION_SKIP_TO_PREVIOUS
        }
        if (currentIndexOnQueue < size - 1) {
            actions = actions or PlaybackState.ACTION_SKIP_TO_NEXT
        }
    }
    return actions
}

جاوا

private void updatePlaybackState() {
    long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
    if (mediaPlayer != null && mediaPlayer.isPlaying()) {
        position = mediaPlayer.getCurrentPosition();
    }
    PlaybackState.Builder stateBuilder = new PlaybackState.Builder()
            .setActions(getAvailableActions());
    stateBuilder.setState(mState, position, 1.0f);
    session.setPlaybackState(stateBuilder.build());
}

private long getAvailableActions() {
    long actions = PlaybackState.ACTION_PLAY_PAUSE |
            PlaybackState.ACTION_PLAY_FROM_MEDIA_ID |
            PlaybackState.ACTION_PLAY_FROM_SEARCH;
    if (playingQueue == null || playingQueue.isEmpty()) {
        return actions;
    }
    if (mState == PlaybackState.STATE_PLAYING) {
        actions |= PlaybackState.ACTION_PAUSE;
    } else {
        actions |= PlaybackState.ACTION_PLAY;
    }
    if (currentIndexOnQueue > 0) {
        actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
    }
    if (currentIndexOnQueue < playingQueue.size() - 1) {
        actions |= PlaybackState.ACTION_SKIP_TO_NEXT;
    }
    return actions;
}

به‌روزرسانی فراداده‌های رسانه‌ای

MediaMetadata با استفاده از متد setMetadata() تنظیم کنید. این متد فقط یک بار برای هر شیء که پخش می‌شود فراخوانی می‌شود. این متد به شما امکان می‌دهد اطلاعاتی در مورد رسانه، از جمله عنوان، زیرنویس، هنرمند، اثر هنری و غیره، به جلسه رسانه ارائه دهید. مثال زیر مختص موسیقی است و فرض می‌کند که داده‌های آهنگ در یک کلاس داده سفارشی، MediaData ، ذخیره می‌شوند:

کاتلین

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

جاوا

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.putBitmap(MediaMetadata.METADATA_KEY_ART,
            myData.artBitmap);
    // Add any other fields you have for your data as well
    session.setMetadata(metadataBuilder.build());
}