Music service: Expose supported actions
This commit is contained in:
parent
5c690f7bc8
commit
2a25db9433
@ -10,12 +10,12 @@ import android.media.AudioManager
|
|||||||
import android.media.MediaMetadata
|
import android.media.MediaMetadata
|
||||||
import android.media.session.MediaController
|
import android.media.session.MediaController
|
||||||
import android.media.session.MediaSession
|
import android.media.session.MediaSession
|
||||||
|
import android.media.session.PlaybackState.CustomAction
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
import android.util.Log
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
@ -57,6 +57,8 @@ interface MusicService {
|
|||||||
val position: Flow<Long?>
|
val position: Flow<Long?>
|
||||||
val duration: Flow<Long?>
|
val duration: Flow<Long?>
|
||||||
|
|
||||||
|
val supportedActions: Flow<SupportedActions>
|
||||||
|
|
||||||
val lastPlayerPackage: String?
|
val lastPlayerPackage: String?
|
||||||
|
|
||||||
fun next()
|
fun next()
|
||||||
@ -203,7 +205,12 @@ internal class MusicServiceImpl(
|
|||||||
send(lastPosition)
|
send(lastPosition)
|
||||||
return@collectLatest
|
return@collectLatest
|
||||||
}
|
}
|
||||||
while(isActive) {
|
if (state.position < 0 || state.lastPositionUpdateTime == 0L) {
|
||||||
|
send(null)
|
||||||
|
lastPosition = null
|
||||||
|
return@collectLatest
|
||||||
|
}
|
||||||
|
while (isActive) {
|
||||||
val offset = SystemClock.elapsedRealtime() - state.lastPositionUpdateTime
|
val offset = SystemClock.elapsedRealtime() - state.lastPositionUpdateTime
|
||||||
val position = state.position + offset
|
val position = state.position + offset
|
||||||
lastPosition = position
|
lastPosition = position
|
||||||
@ -356,7 +363,7 @@ internal class MusicServiceImpl(
|
|||||||
private var lastDuration: Long? = null
|
private var lastDuration: Long? = null
|
||||||
get() {
|
get() {
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
field = preferences.getLong(PREFS_KEY_DURATION, -1).takeIf { it >= 0 }
|
field = preferences.getLong(PREFS_KEY_DURATION, -1).takeIf { it > 0 }
|
||||||
}
|
}
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
@ -373,12 +380,21 @@ internal class MusicServiceImpl(
|
|||||||
send(lastDuration)
|
send(lastDuration)
|
||||||
return@collectLatest
|
return@collectLatest
|
||||||
}
|
}
|
||||||
val duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION)
|
val duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION).takeIf { it > 0 }
|
||||||
lastDuration = duration
|
lastDuration = duration
|
||||||
send(duration.takeIf { it > 0 })
|
send(duration)
|
||||||
}
|
}
|
||||||
}.shareIn(scope, SharingStarted.WhileSubscribed(), 1)
|
}.shareIn(scope, SharingStarted.WhileSubscribed(), 1)
|
||||||
|
|
||||||
|
override val supportedActions: Flow<SupportedActions> = channelFlow {
|
||||||
|
currentState.collectLatest { state ->
|
||||||
|
if (state == null) {
|
||||||
|
send(SupportedActions())
|
||||||
|
return@collectLatest
|
||||||
|
}
|
||||||
|
send(SupportedActions(state.actions, state.customActions))
|
||||||
|
}
|
||||||
|
}.shareIn(scope, SharingStarted.WhileSubscribed(), 1)
|
||||||
|
|
||||||
private suspend fun loadBitmapFromUri(uri: Uri, size: Int): Bitmap? {
|
private suspend fun loadBitmapFromUri(uri: Uri, size: Int): Bitmap? {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
package de.mm20.launcher2.music
|
||||||
|
|
||||||
|
import android.media.session.PlaybackState
|
||||||
|
import android.media.session.PlaybackState.CustomAction
|
||||||
|
|
||||||
|
data class SupportedActions(
|
||||||
|
val stop: Boolean = false,
|
||||||
|
val skipToNext: Boolean = true,
|
||||||
|
val skipToPrevious: Boolean = true,
|
||||||
|
val fastForward: Boolean = false,
|
||||||
|
val rewind: Boolean = false,
|
||||||
|
val seekTo: Boolean = false,
|
||||||
|
val setPlaybackSpeed: Boolean = false,
|
||||||
|
val setRating: Boolean = false,
|
||||||
|
val customActions: List<CustomAction> = emptyList()
|
||||||
|
) {
|
||||||
|
constructor(actions: Long?, customActions: List<CustomAction>?) : this(
|
||||||
|
stop = actions?.and(PlaybackState.ACTION_STOP) == PlaybackState.ACTION_STOP,
|
||||||
|
skipToNext = actions?.and(PlaybackState.ACTION_SKIP_TO_NEXT) == PlaybackState.ACTION_SKIP_TO_NEXT,
|
||||||
|
skipToPrevious = actions?.and(PlaybackState.ACTION_SKIP_TO_PREVIOUS) == PlaybackState.ACTION_SKIP_TO_PREVIOUS,
|
||||||
|
fastForward = actions?.and(PlaybackState.ACTION_FAST_FORWARD) == PlaybackState.ACTION_FAST_FORWARD,
|
||||||
|
rewind = actions?.and(PlaybackState.ACTION_REWIND) == PlaybackState.ACTION_REWIND,
|
||||||
|
seekTo = actions?.and(PlaybackState.ACTION_SEEK_TO) == PlaybackState.ACTION_SEEK_TO,
|
||||||
|
setPlaybackSpeed = actions?.and(PlaybackState.ACTION_SET_PLAYBACK_SPEED) == PlaybackState.ACTION_SET_PLAYBACK_SPEED,
|
||||||
|
setRating = actions?.and(PlaybackState.ACTION_SET_RATING) == PlaybackState.ACTION_SET_RATING,
|
||||||
|
customActions = customActions ?: emptyList(),
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user