پیاده‌سازی جلسه رسانه

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

کاتلین

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());
}