Is there any way to listen to the event of volume change on Android, without just taking over the volume buttons?
The only thing I've found that works is here, but it works only after the volume control has disappeared.
Not all devices have volume buttons, and I need to capture the volume changes as soon as they occur, and not after the volume dialog is gone.
Note: I'm talking about music/media volume, which is what the OS handles by default when changing volume within apps.
For those using kotlin flows, you can use the following approach to listen to volume changes for a specific stream:
val Context.musicVolumeFlow
get() = callbackFlow {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.getIntExtra("android.media.EXTRA_VOLUME_STREAM_TYPE", 0)) {
AudioManager.STREAM_MUSIC -> trySend(
intent.getIntExtra(
"android.media.EXTRA_VOLUME_STREAM_VALUE",
0
)
)
}
}
}
registerReceiver(receiver, IntentFilter("android.media.VOLUME_CHANGED_ACTION"))
awaitClose { unregisterReceiver(receiver) }
}
You can then collect it as follows from an Activity or Service:
lifecycleScope.launch {
musicVolumeFlow.collect { Log.d("AppLog", "stream volume: $it") }
}
Notice this example is only interested in AudioManager.STREAM_MUSIC
. Make sure to target the audio stream relevant to your application.