تنفيذ جلسة وسائط

أنشئ MediaSession عندما يكون تطبيقك بصدد تشغيل الوسائط. يوضّح مقتطف الرمز التالي مثالاً على كيفية ضبط معاودة الاتصال والعلامات المناسبة:

Kotlin

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

Java

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

بدء جلسة وسائط

احرص أيضًا على طلب setActive(true) عند بدء التشغيل. يجب أن يطلب تطبيقك أيضًا الحصول على أولويّة الصوت، كما هو موضّح في مقالة إدارة أولويّة الصوت. يتم عرض هذه الخطوات في المثال التالي:

Kotlin

fun handlePlayRequest() {
    tryToGetAudioFocus()

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

Java

private void handlePlayRequest() {

    tryToGetAudioFocus();

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

تعديل حالة التشغيل

عدِّل حالة التشغيل في MediaSession لتعكس حالة الوسائط الحالية:

Kotlin

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
}

Java

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:

Kotlin

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

Java

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