Listening to MEDIA volume changes has been working for me perfectly.
But now, I need to detect when a user adjusts the Ring & notification volume
via Sound & vibration
touch sliders on the smartphone’s screen.
For that, I resorted to ContentObserver and implemented:
import android.content.Context;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
public class VolumeObserver extends ContentObserver {
private final Context context;
private int lastRingVolume, lastNotificationVolume;
public VolumeObserver(Handler handler, Context context) {
super(handler);
this.context = context;
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
lastRingVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
lastRingVolume = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange);
if (uri != null && uri.toString().contains("volume")) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int currentRingVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
int currentNotificationVolume = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
if (currentRingVolume != lastRingVolume || currentNotificationVolume != lastNotificationVolume) {
Log.v("TAG", "ringVolume: " + lastRingVolume + "-->" + currentRingVolume + ", notificationVolume: " + lastNotificationVolume + "-->" + currentNotificationVolume);
lastRingVolume = currentRingVolume;
lastNotificationVolume = currentNotificationVolume;
}
else {
Log.w("TAG", "ringVolume: " + lastRingVolume + "===" + currentRingVolume + ", notificationVolume: " + lastNotificationVolume + "===" + currentNotificationVolume);
}
}
}
}
Including the proper register/unregister in the app’s main activity.
The problem with my implementation is those events are only received when I press the volume UP/DOWN buttons (correspond to KEYCODE_VOLUME_UP
and `KEYCODE_VOLUME_DOWN). That is, at that point there is no chance for the RING volume to change, because it can only change later, when the Sound & vibration settings screen is displayed:
I tried to resort to a BroadcastReceiver based implementation, but I am getting the same behavior: Events are only received on the hardware key press.
I am therefore out of ideas, other then inefficiently polling AudioManager.getStreamVolume(AudioManager.STREAM_RING)
…
Am I missing something? Is polling really the only way to monitor Ring & notification volume
slider changes?