Reputation: 1819
Is there any way to listen for volume changes with an Android service and react to that?
Btw: How does the Google music app allow the user to control the media volume even when the music is playing in the background?
Upvotes: 14
Views: 15892
Reputation: 2427
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 a Service (LifecycleService
in this case but you can use your own coroutine scope):
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 streams relevant to your application.
Upvotes: 0
Reputation: 24233
Check out registerMediaButtonEventReceiver(ComponentName broadcastReceiver);
Define a BroadcastReceiver
that handles ACTION_MEDIA_BUTTON
. The recieved intent
includes a single extra field, EXTRA_KEY_EVENT
, containing the key event that caused the broadcast. You can use this key event to get which key was pressed.
EDIT:
This is just a sample code. syntax errors may be there.
// in onCreate of activity
registerMediaButtonEventReceiver(mediaReceiver );
// later somewhere in activity.
MediaButton_Receiver mediaReceiver = new MediaButton_Receiver();
class MediaButton_Receiver implements BroadcastReceiver {
void onReceive(Intent intent) {
KeyEvent ke = (KeyEvent)intent.getExtra(Intent.EXTRA_KEY_EVENT);
if (ke .getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
}
// Similarly other key codes .......
}
}
Unregister the receiver in onPause()
or onStop()
Upvotes: 12