所以基本上我稍微简化了UAMP播放器。
我想在前台通知上设置自定义操作(添加/删除等)并动态更改图标:
这是我的 PlayerNotificationManager 包装器代码:
const val ACTION_REMOVE_LIKE = "com.romeat.smashup.media.REMOVE_LIKE_FROM_TRACK"
const val ACTION_ADD_LIKE = "com.romeat.smashup.media.ADD_LIKE_TO_TRACK"
/**
* A wrapper class for ExoPlayer's PlayerNotificationManager.
*/
internal class SmashupNotificationManager(
private val context: Context,
private val sessionToken: MediaSessionCompat.Token,
notificationListener: PlayerNotificationManager.NotificationListener
) {
private var notificationManager: PlayerNotificationManager
private var builder: PlayerNotificationManager.Builder
private val platformNotificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
init {
val mediaController = MediaControllerCompat(context, sessionToken)
builder = PlayerNotificationManager.Builder(
context,
NOW_PLAYING_NOTIFICATION_ID,
NOW_PLAYING_CHANNEL_ID)
with (builder) {
setMediaDescriptionAdapter(DescriptionAdapter(mediaController))
setNotificationListener(notificationListener)
setChannelNameResourceId(R.string.notification_channel)
setChannelDescriptionResourceId(R.string.notification_channel_description)
setCustomActionReceiver(
object : PlayerNotificationManager.CustomActionReceiver {
override fun createCustomActions(
context: Context,
instanceId: Int
): MutableMap<String, NotificationCompat.Action> {
return mutableMapOf(
Pair(ACTION_ADD_LIKE, NotificationCompat.Action(
R.drawable.ic_baseline_favorite_border_24, "add like",
PendingIntent.getBroadcast(
context,
123,
Intent(ACTION_ADD_LIKE).setPackage(context.packageName),
PendingIntent.FLAG_IMMUTABLE
)
)),
)
}
override fun getCustomActions(player: Player): MutableList<String> {
return mutableListOf(ACTION_ADD_LIKE)
}
override fun onCustomAction(player: Player, action: String, intent: Intent) { }
}
)
}
notificationManager = builder.build()
notificationManager.setMediaSessionToken(sessionToken)
notificationManager.setUseRewindAction(false)
notificationManager.setUseFastForwardAction(false)
}
fun updateLikeButton() {
// Can get here with no problem.
// Basically I want to replace CustomActionReceiver:
builder.setCustomActionReceiver(object : PlayerNotificationManager.CustomActionReceiver {
override fun createCustomActions(
context: Context,
instanceId: Int
): MutableMap<String, NotificationCompat.Action> {
return mutableMapOf(
Pair(ACTION_REMOVE_LIKE, NotificationCompat.Action(
R.drawable.ic_baseline_favorite_24, "remove like",
PendingIntent.getBroadcast(
context,
123,
Intent(ACTION_REMOVE_LIKE).setPackage(context.packageName),
PendingIntent.FLAG_IMMUTABLE
)
))
)
}
override fun getCustomActions(player: Player): MutableList<String> {
return mutableListOf(ACTION_REMOVE_LIKE)
}
override fun onCustomAction(player: Player, action: String, intent: Intent) { }
})
...
// But I can't use .notify() because second parameter is of PlayerNotificationManager type, not Notification type
platformNotificationManager.notify(NOW_PLAYING_NOTIFICATION_ID, builder.build())
}
// other code, like DescriptionAdapter etc...
}
我设法设置自定义操作并响应新闻事件,但我找不到更改图标的方法。 我正在尝试替换
CustomActionReceiver
函数中的 updateLikeButton()
,但无法调用 notify()
并更新通知本身。
我很好奇一般情况下是否可以使用
PlayerNotificationManager
?
经过多次尝试,我发现 MutableMap 的神奇之处在于
private var customActionRepeat: NotificationCompat.Action? = null
private var customPendingAction: PendingIntent? = null
private val repeatAction = "repeatAction"
private val repeatActionOff = "actionOff"
private val repeatActionOn = "actionOn"
private var customActionMutableMap: MutableMap<String, NotificationCompat.Action>? = mutableMapOf()
private var customActionReceiver = CustomActionReceiver()
//set the customActionReceiver to your PlayerNotificationManager
onCreate(){
customPendingAction = PendingIntent.getService(
this, 0,
Intent(this, PlayerService::class.java).apply {
action = Constants.ACTION_REPEAT
}, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
)
customActionRepeat = NotificationCompat.Action.Builder(
R.drawable.repeat_on,
"Repeat on",
customPendingAction
).build()
customActionMutableMap!![repeatAction] = customActionRepeat!!
}
private inner class CustomActionReceiver : PlayerNotificationManager.CustomActionReceiver {
override fun createCustomActions(
context: Context,
instanceId: Int
): MutableMap<String, NotificationCompat.Action> {
return customActionMutableMap!!
}
override fun getCustomActions(player: Player): MutableList<String> {
return mutableListOf(repeatAction)
}
override fun onCustomAction(player: Player, action: String, intent: Intent) {
when(action){
repeatActionOn ->{
player.repeatMode = Player.REPEAT_MODE_ONE
repeatMode.value = RepeatModeUtil.REPEAT_TOGGLE_MODE_ONE
customActionRepeat = NotificationCompat.Action.Builder(
R.drawable.repeat_one_on,
"Repeat one on",
customPendingAction
).build()
customActionMutableMap!![repeatAction] = customActionRepeat!!
}
repeatActionOff ->{
player.repeatMode = Player.REPEAT_MODE_ALL
repeatMode.value = RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL
customActionRepeat = NotificationCompat.Action.Builder(
R.drawable.repeat_on,
"Repeat on",
customPendingAction
).build()
customActionMutableMap!![repeatAction] = customActionRepeat!!
}
}
}
}
所以就这样称呼吧
//to turn on
customActionReceiver.onCustomAction(
player = mediaSession?.player!!,
action = repeatActionOn,
intent = Intent(this, PlayerService::class.java)
)
//to turn off
customActionReceiver.onCustomAction(
player = mediaSession?.player!!,
action = repeatActionOff,
intent = Intent(this, PlayerService::class.java)
)