Modernize AudioFocusHandler
This commit is contained in:
parent
8640d39438
commit
5f8e3ce851
|
@ -1,8 +1,14 @@
|
||||||
package org.moire.ultrasonic.service
|
package org.moire.ultrasonic.service
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.media.AudioAttributes
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.AudioManager.OnAudioFocusChangeListener
|
import android.media.AudioManager.OnAudioFocusChangeListener
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.media.AudioAttributesCompat
|
||||||
|
import androidx.media.AudioFocusRequestCompat
|
||||||
|
import androidx.media.AudioManagerCompat
|
||||||
import org.koin.java.KoinJavaComponent.inject
|
import org.koin.java.KoinJavaComponent.inject
|
||||||
import org.moire.ultrasonic.domain.PlayerState
|
import org.moire.ultrasonic.domain.PlayerState
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
|
@ -11,54 +17,109 @@ import timber.log.Timber
|
||||||
|
|
||||||
class AudioFocusHandler(private val context: Context) {
|
class AudioFocusHandler(private val context: Context) {
|
||||||
// TODO: This is a circular reference, try to remove it
|
// TODO: This is a circular reference, try to remove it
|
||||||
|
// This should be doable by using the native MediaController framework
|
||||||
private val mediaPlayerControllerLazy = inject(MediaPlayerController::class.java)
|
private val mediaPlayerControllerLazy = inject(MediaPlayerController::class.java)
|
||||||
|
|
||||||
|
private val audioManager by lazy {
|
||||||
|
context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
|
}
|
||||||
|
|
||||||
|
private val preferences by lazy {
|
||||||
|
Util.getPreferences(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val lossPref: Int
|
||||||
|
get() = preferences.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")!!.toInt()
|
||||||
|
|
||||||
|
private val audioAttributesCompat by lazy {
|
||||||
|
AudioAttributesCompat.Builder()
|
||||||
|
.setUsage(AudioAttributesCompat.USAGE_MEDIA)
|
||||||
|
.setContentType(AudioAttributesCompat.CONTENT_TYPE_MUSIC)
|
||||||
|
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
fun requestAudioFocus() {
|
fun requestAudioFocus() {
|
||||||
if (!hasFocus) {
|
if (!hasFocus) {
|
||||||
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
||||||
hasFocus = true
|
hasFocus = true
|
||||||
|
AudioManagerCompat.requestAudioFocus(audioManager, focusRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val listener = OnAudioFocusChangeListener { focusChange ->
|
||||||
|
|
||||||
audioManager.requestAudioFocus(object : OnAudioFocusChangeListener {
|
val mediaPlayerController = mediaPlayerControllerLazy.value
|
||||||
override fun onAudioFocusChange(focusChange: Int) {
|
|
||||||
val mediaPlayerController = mediaPlayerControllerLazy.value
|
when (focusChange) {
|
||||||
if ((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) && !mediaPlayerController.isJukeboxEnabled) {
|
AudioManager.AUDIOFOCUS_GAIN -> {
|
||||||
Timber.v("Lost Audio Focus")
|
Timber.v("Regained Audio Focus")
|
||||||
if (mediaPlayerController.playerState === PlayerState.STARTED) {
|
if (pauseFocus) {
|
||||||
val preferences = Util.getPreferences(context)
|
pauseFocus = false
|
||||||
val lossPref = preferences.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")!!.toInt()
|
mediaPlayerController.start()
|
||||||
if (lossPref == 2 || lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
|
} else if (lowerFocus) {
|
||||||
lowerFocus = true
|
lowerFocus = false
|
||||||
mediaPlayerController.setVolume(0.1f)
|
mediaPlayerController.setVolume(1.0f)
|
||||||
} else if (lossPref == 0 || lossPref == 1) {
|
}
|
||||||
pauseFocus = true
|
}
|
||||||
mediaPlayerController.pause()
|
AudioManager.AUDIOFOCUS_LOSS -> {
|
||||||
}
|
if (!mediaPlayerController.isJukeboxEnabled) {
|
||||||
|
hasFocus = false
|
||||||
|
mediaPlayerController.pause()
|
||||||
|
AudioManagerCompat.abandonAudioFocusRequest(audioManager, focusRequest)
|
||||||
|
Timber.v("Abandoned Audio Focus")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
|
||||||
|
if (!mediaPlayerController.isJukeboxEnabled) {
|
||||||
|
Timber.v("Lost Audio Focus")
|
||||||
|
|
||||||
|
if (mediaPlayerController.playerState === PlayerState.STARTED) {
|
||||||
|
if (lossPref == 0 || lossPref == 1) {
|
||||||
|
pauseFocus = true
|
||||||
|
mediaPlayerController.pause()
|
||||||
}
|
}
|
||||||
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
|
|
||||||
Timber.v("Regained Audio Focus")
|
|
||||||
if (pauseFocus) {
|
|
||||||
pauseFocus = false
|
|
||||||
mediaPlayerController.start()
|
|
||||||
} else if (lowerFocus) {
|
|
||||||
lowerFocus = false
|
|
||||||
mediaPlayerController.setVolume(1.0f)
|
|
||||||
}
|
|
||||||
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS && !mediaPlayerController.isJukeboxEnabled) {
|
|
||||||
hasFocus = false
|
|
||||||
mediaPlayerController.pause()
|
|
||||||
audioManager.abandonAudioFocus(this)
|
|
||||||
Timber.v("Abandoned Audio Focus")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
|
}
|
||||||
Timber.v("Got Audio Focus")
|
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
|
||||||
|
if (!mediaPlayerController.isJukeboxEnabled) {
|
||||||
|
Timber.v("Lost Audio Focus")
|
||||||
|
|
||||||
|
if (mediaPlayerController.playerState === PlayerState.STARTED) {
|
||||||
|
if (lossPref == 2 || lossPref == 1) {
|
||||||
|
lowerFocus = true
|
||||||
|
mediaPlayerController.setVolume(0.1f)
|
||||||
|
} else if (lossPref == 0 || lossPref == 1) {
|
||||||
|
pauseFocus = true
|
||||||
|
mediaPlayerController.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val focusRequest: AudioFocusRequestCompat by lazy {
|
||||||
|
AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
|
||||||
|
.setAudioAttributes(audioAttributesCompat)
|
||||||
|
.setWillPauseWhenDucked(true)
|
||||||
|
.setOnAudioFocusChangeListener(listener)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var hasFocus = false
|
private var hasFocus = false
|
||||||
private var pauseFocus = false
|
private var pauseFocus = false
|
||||||
private var lowerFocus = false
|
private var lowerFocus = false
|
||||||
|
|
||||||
|
// TODO: This can be removed if we switch to androidx.media2.player
|
||||||
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
fun getAudioAttributes(): AudioAttributes {
|
||||||
|
return AudioAttributes.Builder()
|
||||||
|
.setUsage(AudioAttributes.USAGE_MEDIA)
|
||||||
|
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||||
|
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue