Question

in my app I have a VerticalSeekBar (some custom implementation of SeekBar) whos progress should change when the user changes media volume using the hardware buttons. Below is a half-working solution using a ContentObserver:

      public class SettingsContentObserver extends ContentObserver {

     private VerticalSeekBar sb;
     private AudioManager am;

public SettingsContentObserver(Handler handler, VerticalSeekBar sb, AudioManager am) {
    super(handler);
    this.sb = sb;
    this.am = am;

}

@Override
public boolean deliverSelfNotifications() {
    return super.deliverSelfNotifications();
}

@Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    sb.setProgress(am.getStreamVolume(AudioManager.STREAM_MUSIC));

}
    }

Activity:

        @Override
protected void onResume() {
    super.onResume();
    mSettingsContentObserver = new SettingsContentObserver( new Handler(), vBar, audioMan ); 
    this.getApplicationContext().getContentResolver().registerContentObserver( 
        android.provider.Settings.System.CONTENT_URI, true, 
        mSettingsContentObserver );

}

The issue: volume changes are detected BUT there's a few seconds delay until they get detected and SeekBar's progress changes.

The question: is there a more reliable way to listen for volume changes on a particular volume stream? Please share you solution in case you have some

Was it helpful?

Solution

I already made a solution that monitors volume level while in a phone call, so this should be similar.

You can either listen for the key presses in your activity (onKey) and check for the corresponding keyCode (VOLUME_UP or VOLUME_DOWN).

Or, if you can't listen for the key events for some reason (some remote view), just poll the volume level at a fast enough frequency:

  1. Use am.getStreamVolume(AudioManager.STREAM_MUSIC) to poll the volume level.

  2. Run this at your desired frequency. For example:

        private Runnable mVolumeUpdateRunnable = new Runnable() {
        public void run() {
            if (shouldUpdate)
            {
                    updateCurrentVolume();
                    new Handler().postDelayed(mVolumeUpdateRunnable, VOLUME_SAMPLING_DELAY);
            }
        }
    };
    

The calls are not expensive so it shouldn't be a big problem to update at a high frequency.

OTHER TIPS

polling stream vol at a high frequency increase cpu usage,in my case it was 14%

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top