问题描述
我已经检查了有关 ContentObserver 的其他问题,但没有找到解决方案。
我想在 STREAM_MUSIC 的音量发生变化时立即获得回调。不仅在按下音量按钮时,而且在通过例如以编程方式更改音量时音频管理器。 问题是, onChange() 并不总是被调用,只是偶尔被调用。我下面的测试有时会失败,有时会成功(即使我等了 10 秒)。 我做错了什么?
最小工作示例: 内容观察者:
class AudioContentObserver(
private val context: Context,) : ContentObserver(Handler(HandlerThread("AudioContentObserverThread").apply { start() }.looper)) {
private val audioManager = context.getSystemService(Context.AUdio_SERVICE) as? AudioManager
private var lastVolIndex: Int = -1
var onChangeCalled = false
override fun onChange(selfChange: Boolean) = this.onChange(selfChange,null)
override fun onChange(selfChange: Boolean,uri: Uri?) {
audioManager ?: return
val volIndex = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
if (volIndex == lastVolIndex) return // onChange() triggered by other system setting update
println("onChange() called!")
onChangeCalled = true
}
fun registerObserver() {
audioManager ?: return
// no URI just for volume changes,so listen to all system setting changes
context.contentResolver.registerContentObserver(
android.provider.Settings.System.CONTENT_URI,true,this
)
lastVolIndex = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
}
fun unregisterObserver() {
audioManager ?: return // ContentObserver was never registered
context.contentResolver.unregisterContentObserver(this)
}
}
这是我的测试:
import android.content.Context
import android.media.AudioManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.awaitility.Duration
import org.awaitility.kotlin.atMost
import org.awaitility.kotlin.await
import org.awaitility.kotlin.untilAsserted
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class AudioContentObserverTest {
lateinit var context: Context
lateinit var observer: AudioContentObserver
@Before
fun setup() {
context = ApplicationProvider.getApplicationContext<Context>()
observer = AudioContentObserver(context)
}
@After
fun cleanup() {
observer.unregisterObserver()
}
@Test
fun should_get_onChange_callback_when_volume_changes() {
val audioManager: AudioManager =
context.getSystemService(Context.AUdio_SERVICE) as AudioManager
// set volume index to 1 before we register ContentObserver
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,1,AudioManager.FLAG_SHOW_UI)
observer.registerObserver()
// changing volume while ContentObserver observes CONTENT_URI
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,2,AudioManager.FLAG_SHOW_UI)
// timeout after 2 sec if onChange() was not called
await atMost Duration.TWO_SECONDS untilAsserted { Assert.assertTrue(observer.onChangeCalled) }
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)