Otter-App-Android-Funkwhale/app/src/main/java/com/github/apognu/otter/playback/MediaControlsManager.kt

117 lines
3.9 KiB
Kotlin
Raw Normal View History

2019-08-19 16:50:33 +02:00
package com.github.apognu.otter.playback
import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
2019-08-19 16:50:33 +02:00
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.media.app.NotificationCompat.MediaStyle
import androidx.media.session.MediaButtonReceiver
import com.github.apognu.otter.Otter
2019-08-19 16:50:33 +02:00
import com.github.apognu.otter.R
import com.github.apognu.otter.activities.MainActivity
import com.github.apognu.otter.utils.AppContext
import com.github.apognu.otter.utils.maybeNormalizeUrl
2020-07-13 23:32:42 +02:00
import com.github.apognu.otter.models.domain.Track
2019-08-19 16:50:33 +02:00
import com.squareup.picasso.Picasso
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Default
2019-08-19 16:50:33 +02:00
import kotlinx.coroutines.launch
class MediaControlsManager(val context: Service, private val scope: CoroutineScope, private val mediaSession: MediaSessionCompat) {
2019-08-19 16:50:33 +02:00
companion object {
const val NOTIFICATION_ACTION_OPEN_QUEUE = 0
}
2019-10-21 11:51:32 +02:00
private var notification: Notification? = null
2019-08-19 16:50:33 +02:00
fun updateNotification(track: Track?, playing: Boolean) {
if (notification == null && !playing) return
track?.let {
val stateIcon = when (playing) {
true -> R.drawable.pause
false -> R.drawable.play
}
scope.launch(Default) {
2019-08-19 16:50:33 +02:00
val openIntent = Intent(context, MainActivity::class.java).apply { action = NOTIFICATION_ACTION_OPEN_QUEUE.toString() }
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, 0)
2020-08-08 14:51:39 +02:00
val coverUrl = maybeNormalizeUrl(track.album?.cover())
2019-08-19 16:50:33 +02:00
notification = NotificationCompat.Builder(
context,
AppContext.NOTIFICATION_CHANNEL_MEDIA_CONTROL
)
.setShowWhen(false)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
2019-08-19 16:50:33 +02:00
.setStyle(
MediaStyle()
.setMediaSession(mediaSession.sessionToken)
.setShowActionsInCompactView(0, 1, 2)
)
.setSmallIcon(R.drawable.ottershape)
2019-10-22 21:56:33 +02:00
.run {
coverUrl?.let {
try {
setLargeIcon(Picasso.get().load(coverUrl).get())
} catch (_: Exception) {
}
return@run this
}
this
2019-10-22 21:56:33 +02:00
}
2019-08-19 16:50:33 +02:00
.setContentTitle(track.title)
2020-07-13 23:32:42 +02:00
.setContentText(track.artist?.name)
2019-08-19 16:50:33 +02:00
.setContentIntent(openPendingIntent)
.setChannelId(AppContext.NOTIFICATION_CHANNEL_MEDIA_CONTROL)
.addAction(
action(
R.drawable.previous, context.getString(R.string.control_previous),
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
2019-08-19 16:50:33 +02:00
)
)
.addAction(
action(
stateIcon, context.getString(R.string.control_toggle),
PlaybackStateCompat.ACTION_PLAY_PAUSE
2019-08-19 16:50:33 +02:00
)
)
.addAction(
action(
R.drawable.next, context.getString(R.string.control_next),
PlaybackStateCompat.ACTION_SKIP_TO_NEXT
2019-08-19 16:50:33 +02:00
)
)
.build()
notification?.let {
if (playing) {
context.startForeground(AppContext.NOTIFICATION_MEDIA_CONTROL, it)
} else {
NotificationManagerCompat.from(context).notify(AppContext.NOTIFICATION_MEDIA_CONTROL, it)
}
2019-08-19 16:50:33 +02:00
}
Otter.get().mediaSession.connector.invalidateMediaSessionMetadata()
2019-08-19 16:50:33 +02:00
}
}
}
fun remove() {
NotificationManagerCompat.from(context).cancel(AppContext.NOTIFICATION_MEDIA_CONTROL)
}
private fun action(icon: Int, title: String, id: Long): NotificationCompat.Action {
return MediaButtonReceiver.buildMediaButtonPendingIntent(context, id).run {
NotificationCompat.Action.Builder(icon, title, this).build()
2019-08-19 16:50:33 +02:00
}
}
}