How to handle changes from MediaSession remote volume overlay?

JavaAndroid

Java Problem Overview


I am trying to implement a remote volume control. It already works to control the volume with the hardware volume keys but when I try to move the slider in the MediaSession remote volume overlay, the VolumeProviderCompat.onAdjustVolume(..) callback is not called. I also tried other callbacks like MediaSessionCompat.Callback.onMediaButtonEvent(..) or VolumeProviderCompat.onSetVolumeTo(..) but they are not called at all.

If you don't know what I mean with the "MediaSession remote volume overlay", here is a screenshot:

enter image description here

I created a demo project which you can download here: <https://github.com/SaschaZ/VolumeProviderDemo>;.

Here are the related parts of my DemoActivity:

public class DemoActivity extends AppCompatActivity {

    ...

    private Notification createNotification(@NonNull final DemoVolumeController demoVolumeController) {
        Log.d(TAG, "createNotification()");

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setSmallIcon(R.mipmap.ic_launcher);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (session != null) {
                session.release();
            }
            session = new MediaSessionCompat(this, "demoMediaSession");
            session.setPlaybackState(new PlaybackStateCompat.Builder()
                .setState(PlaybackStateCompat.STATE_PLAYING, 1, 1.0f)
                .build());
            session.setPlaybackToRemote(createVolumeProvider(demoVolumeController));
            session.setActive(true);
        }

        return builder.build();
    }

    private VolumeProviderCompat createVolumeProvider(@NonNull final DemoVolumeController demoVolumeController) {
        // I don't use this callback directly, but I need to set it or my VolumeProvider will not work. (sounds
        // strange but I tried it several times)
        session.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public boolean onMediaButtonEvent(final Intent mediaButtonEvent) {
                Log.d(TAG, "onMediaButtonEvent() called with: " + "mediaButtonEvent = [" + mediaButtonEvent + "]");
                return super.onMediaButtonEvent(mediaButtonEvent);
            }
        });

        return new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE,
            100,
            demoVolumeController.getVolume()) {
            @Override
            public void onAdjustVolume(final int direction) {
                final int volume = demoVolumeController.setVolumeRelative(direction);
                showVolume(volume);

                Log.d(TAG, "onAdjustVolume() called with: " + "direction = [" + direction + "] - " +
                    "new volume=" + volume);

                // Nasty hack to get sync with the volume overlay of Android. setCurrentVolume does not work :(
                session.setPlaybackToRemote(createVolumeProvider(demoVolumeController));
            }
        };
    }

    ...
}

Any hints? Thank you in advance!

Java Solutions


Solution 1 - Java

Using the Activity’s setVolumeControlStream method—typically within its onCreate method— allows you to specify which audio stream should be controlled by the volume keys while the current Activity is active:

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.audioplayer);

   setVolumeControlStream(AudioManager.STREAM_MUSIC);
}

You can specify any of the available audio streams, but when using the Media Player, you should specify the STREAM_MUSIC stream to make it the focus of the volume keys.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSaschaView Question on Stackoverflow
Solution 1 - JavaMohammad Reza KhahaniView Answer on Stackoverflow