androidvolumeandroid-contentresolvercontentobserver

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?


Solution

  • 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()