Reputation: 221
When I am developing an Android application, how can I detect if volume is set to mute?
How can my application get notified if the volume changes to mute or gets unmuted?
Upvotes: 10
Views: 9980
Reputation: 2427
You can do the following to observe if a specific stream (music in this case) is muted:
val Context.musicMutedFlow
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.getBooleanExtra(
"android.media.EXTRA_STREAM_VOLUME_MUTED",
false
)
)
}
}
}
registerReceiver(receiver, IntentFilter("android.media.STREAM_MUTE_CHANGED_ACTION"))
awaitClose { unregisterReceiver(receiver) }
}
Then, from a ContextWrapper
(e.g., Activity
, Service
), you can collect the flow as follows:
lifecycleScope.launch {
musicMutedFlow.collect { Log.d("Some tag", "Music stream muted: $it") }
}
If, like in the accepted answer, you want to specifically know if the Ring and notification volume is muted, you may instead want to do the following:
val Context.ringAndNotificationMutedFlow
get() = callbackFlow {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val ringerMode = intent.getIntExtra(
AudioManager.EXTRA_RINGER_MODE,
AudioManager.RINGER_MODE_NORMAL
)
trySend(ringerMode != AudioManager.RINGER_MODE_NORMAL)
}
}
registerReceiver(receiver, IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION))
awaitClose { unregisterReceiver(receiver) }
}
The advantage is that the AudioManager
constants used are public and Google would have to mark them for deprecation if they were to change them or remove them.
Upvotes: 0
Reputation: 48602
You can use AudioManager to check volume is mute or not mute.
AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
switch( audio.getRingerMode() ){
case AudioManager.RINGER_MODE_NORMAL:
break;
case AudioManager.RINGER_MODE_SILENT:
break;
case AudioManager.RINGER_MODE_VIBRATE:
break;
}
and for Volume change there is BroadcastReceiver for that.
public class VolumeKeyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Implement Logic
}
}
Register the BroadcastReceiver
VolumeKeyReceiver keyReceiver = new VolumeKeyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.media.VOLUME_CHANGED_ACTION");
registerReceiver(keyReceiver, intentFilter);
Upvotes: 34