Is there a way In Android to listen to Audio Volume Changes only?

I have seen a few answers to similar types of questions, mostly considering the ContentObserver as its solution. Somewhere on the similar lines as under:

getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, new ContentObserver(){...} );

But the Content Observer registered for the CONTENT_URI observes for a lot of other changes as well. Although, we can detect if it was a volume change by checking the difference between the previous volume and current volume, which also seems costly where we require an operation to fetch current volume and a variable to store the previous volume which I am looking to avoid.

So, is there a way we can listen for the Audio Volume Change only?

Answer

I got a solution that works on or above API 16. MediaRouter can be used which reports for the Media Route being used along with the Volume Change events.

Example

mediaRouter = (MediaRouter) owner.getContext().getSystemService(MEDIA_ROUTER_SERVICE);
setupCallback();
mediaRouter.addCallback(ROUTE_TYPE_USER, callback, CALLBACK_FLAG_UNFILTERED_EVENTS);

where setupCallback() is as follows:

private void setupCallback() {
    callback = new MediaRouter.Callback() {

        @Override
        public void onRouteSelected(MediaRouter router, int type, MediaRouter.RouteInfo info) {
        }

        @Override
        public void onRouteUnselected(MediaRouter router, int type, MediaRouter.RouteInfo info) {
        }

        @Override
        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
        }

        @Override
        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
        }

        @Override
        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
        }

        @Override
        public void onRouteGrouped(MediaRouter router, MediaRouter.RouteInfo info, MediaRouter.RouteGroup group, int index) {
        }

        @Override
        public void onRouteUngrouped(MediaRouter router, MediaRouter.RouteInfo info, MediaRouter.RouteGroup group) {
        }

        @Override
        public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo info) {
            Log.d("onRouteVolumeChanged", info.getVolume());
        }
    };
}

You can get the VolumeChanged event with a callback method onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo info) where the volume can be retrieved using info.getVolume()