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

إنشاء MediaSession أثناء تجهيز تطبيقك لتشغيل الوسائط. مقتطف الرمز البرمجي التالي هو مثال على كيفية ضبط علامة الاستدعاء والعلامات المناسبة:

KotlinJava
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) عند بدء التشغيل. يجب أن يطلب تطبيقك أيضًا ميزة "التركيز على الصوت"، كما هو موضّح في إدارة ميزة "التركيز على الصوت". يتم توضيح هذه الخطوات في المثال التالي:

KotlinJava
private fun handlePlayRequest() {

    tryToGetAudioFocus
()

   
if (!session.isActive) {
        session
.isActive = true
   
}
   
...
}
private void handlePlayRequest() {

    tryToGetAudioFocus
();

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

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

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

KotlinJava
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:

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