kevdliu
kevdliu

Reputation: 1819

Volume change listener?

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

Answers (2)

argenkiwi
argenkiwi

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

Ron
Ron

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

Related Questions