From a4f55873ec9143ff122e566f598a2953211a2362 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Fri, 30 Oct 2020 16:06:45 -0600 Subject: [PATCH] Add Audio Focus Use the built-in ExoPlayer AudioFocus functionality to implement Audio Focus [hopefully]. --- .../oxycblt/auxio/playback/PlaybackService.kt | 31 ++++++++++++++++++- .../playback/state/PlaybackStateManager.kt | 4 --- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt index 84d6f9444..ca54335bc 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt @@ -17,14 +17,15 @@ import android.support.v4.media.session.MediaSessionCompat import android.util.Log import android.view.KeyEvent import androidx.core.app.NotificationCompat +import com.google.android.exoplayer2.C import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.SimpleExoPlayer +import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job -import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.conflate @@ -59,6 +60,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { private val playbackManager = PlaybackStateManager.getInstance() private lateinit var mediaSession: MediaSessionCompat private lateinit var systemReceiver: SystemEventReceiver + private var changeIsFromSystem = false private val serviceJob = Job() private val serviceScope = CoroutineScope( @@ -91,6 +93,15 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { handleMediaButtonEvent(mediaButtonEvent) } + // Set up AudioFocus/AudioAttributes + player.setAudioAttributes( + AudioAttributes.Builder() + .setUsage(C.USAGE_MEDIA) + .setContentType(C.CONTENT_TYPE_MUSIC) + .build(), + true + ) + notification = createNotification() // Set up callback for system events @@ -132,6 +143,16 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { } } + override fun onIsPlayingChanged(isPlaying: Boolean) { + // If the change to playing occurred from the system instead of PlaybackStateManager, then + // sync the playing value to PlaybackStateManager to keep it up ton date. + if (isPlaying != playbackManager.isPlaying && changeIsFromSystem) { + playbackManager.setPlayingStatus(isPlaying) + } + + changeIsFromSystem = true + } + override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { // If the song loops while in the LOOP_ONCE mode, then stop looping after that. if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT && @@ -144,6 +165,8 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { // --- PLAYBACK STATE CALLBACK OVERRIDES --- override fun onSongUpdate(song: Song?) { + changeIsFromSystem = false + song?.let { val item = MediaItem.fromUri(it.id.toURI()) player.setMediaItem(item) @@ -157,6 +180,8 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { } override fun onPlayingUpdate(isPlaying: Boolean) { + changeIsFromSystem = false + if (isPlaying && !player.isPlaying) { player.play() @@ -171,6 +196,8 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { } override fun onLoopUpdate(mode: LoopMode) { + changeIsFromSystem = false + when (mode) { LoopMode.NONE -> { player.repeatMode = Player.REPEAT_MODE_OFF @@ -182,6 +209,8 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateCallback { } override fun onSeekConfirm(position: Long) { + changeIsFromSystem = false + player.seekTo(position * 1000) } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 7bc275a0d..f689f9c72 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -389,9 +389,5 @@ class PlaybackStateManager { return newInstance } } - - const val LOOP_NONE = 0 - const val LOOP_ONCE = 1 - const val LOOP_ENDLESS = 2 } }