android 卡片播放,显示“正在播放”卡片

在启动器后面或在后台播放媒体时,TV 应用必须显示“正在播放”卡片。通过此卡片,用户可返回当前正在播放媒体的应用。

当存在活动的 该卡片包含媒体元数据,如专辑封面、名称和应用图标。当用户选择该卡片时,系统会打开相应的应用。

本课程介绍如何利用

496d318ee0c67adec36a3c5d01e2d269.png

图 1. 在后台播放媒体时显示“正在播放”卡片。

启动媒体会话

当您的应用准备播放媒体时,创建一个

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

显示“正在播放”卡片

系统仅为活动会话显示“正在播放”卡片。播放开始时,您必须调用 管理音频焦点中所述。

Kotlin

private fun handlePlayRequest() {

tryToGetAudioFocus()

if (!session.isActive) {

session.isActive = true

}

...

}Java

private void handlePlayRequest() {

tryToGetAudioFocus();

if (!session.isActive()) {

session.setActive(true);

}

...

}

通过调用

更新播放状态

更新

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;

}

显示媒体元数据

使用 以下示例假定您的曲目数据存储在自定义数据类 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());

}

响应用户操作

当用户选择“正在播放”卡片时,系统会打开拥有该会话的应用。如果您的应用向

Kotlin

val pi: PendingIntent = Intent(context, MyActivity::class.java).let { intent ->

PendingIntent.getActivity(

context, 99 /*request code*/,

intent,

PendingIntent.FLAG_UPDATE_CURRENT

)

}

session.setSessionActivity(pi)Java

Intent intent = new Intent(context, MyActivity.class);

PendingIntent pi = PendingIntent.getActivity(context, 99 /*request code*/,

intent, PendingIntent.FLAG_UPDATE_CURRENT);

session.setSessionActivity(pi);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值