SeekBar — Volume — Google Cast

Dmitry Khasanov
ProAndroidDev
Published in
2 min readMar 19, 2019

--

If you are developing media playback application with Google Cast (Chromecast) support you maybe want to implement volume change slider to adjust volume on receiver device (TV, for example) during casting as well as media volume on android phone.

I ran into this issue and in this article I’ll show the solution using Kotlin, Strategy pattern and Lifecycle-aware components. As you may have already guessed SeekBar will be used as a slider.

First of all let’s briefly outline the approach. There is one main user class which purpose is to glue SeekBar with volume controlling. It responsible for handling cast session events and switching between appropriate implementations.

So, we need two volume control implementations: one for AudioManager.STREAM_MUSIC and another one for cast session. According to the Strategy pattern, write abstract class with common interface. Call it Volumizer:

start() and stop() methods used to subscribe and unsubscribe listeners to external volume changes. The rest is obvious.

Then write implementation to adjust music stream on a device. Essentially, it’s a well-known way that used AudioManager to get/set volume and ContentObserver for monitoring volume changing.

Next implement managing the volume of cast receiver. For this we need an instance of CastSession to get/set volume and Cast.Listener for monitoring volume changing. Note that the volume in CastSession is in the range [0.0, 1.0], so we have to adapt it to the base class interface where volume values are integers (like Seekbar has too). For this reason we use VOLUME_STEP and VOLUME_MAX constants — 20 steps with 0.05 weight.

Now let’s write central class of the solution — SeekBarCastAwareVolumizer:

The main points of this class are:

  1. CheckSessionManager.currentCastSession to instantiate proper Volumizer implementation in the constructor.
  2. Using SessionManagerListener to handle starting and ending casting session to change behavior by using differentVolumizers.
  3. In onStop method of activity we must remove all listeners. Otherwise there will be an activity leak.LifecycleObserverallows this class to achieve that and be self-sufficient.
  4. seekBar.isSaveEnabled = false — to disable saving state of the view, because we synсhronizing Seekbar with current volume in onStart.

Wrapping up

Finally, usage of the class looks that way:

Just write one line of code and get the magic — now your SeekBar can change the volume simply playing media on the phone and while streaming to a TV or sound system as well.

Full code you may find here.

--

--