Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chromecast MediaRouteProviderService

I have strange issue, I am creating mediaprovider for chromecast using following code that works fine for first instance, list of devices is shown and once slected I use router.selectRoute(routeinfo); but once I exit app this code unable to find Chromecast device, how ever when I remove app from running apps stack this code works fine again and show devices.

If no device is selected and app is exited using back press then also this code works fine

So what I am doing wrong here? what I think is resources are not cleared when my app exit in simple back pressed.

public class ChromecastRouteProviderService extends MediaRouteProviderService {
final String LOGTAG = "Chromecast";
private static final String CONTROL_CATEGORY = CastMediaControlIntent.categoryForCast(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID);
private static final MediaRouteSelector SELECTOR = new MediaRouteSelector.Builder().addControlCategory(CONTROL_CATEGORY)
        .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK).build();
private IntentFilter controlFilter;

public ChromecastRouteProviderService() {
    controlFilter = new IntentFilter();
}

public void onCreate() {
    super.onCreate();
    controlFilter.addCategory(IAppConstants.CATEGORY);
    controlFilter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
}

@Override
public MediaRouteProvider onCreateMediaRouteProvider() {
    return new ChromecastRouteProvider(this);
}

class ChromecastRouteProvider extends MediaRouteProvider {
    MediaRouter.Callback callback;
    Hashtable routes;

    public ChromecastRouteProvider(Context context) {
        super(context);
        routes = new Hashtable();
        callback = new CastCallBack();
    }

    @Nullable
    @Override
    public RouteController onCreateRouteController(String routeId) {
        MediaRouter.RouteInfo routeInfo = (MediaRouter.RouteInfo) routes.get(routeId);
        if (routeInfo == null) {
            return super.onCreateRouteController(routeId);
        } else {
            return new ChromecastRouteController(getContext(), routeInfo);
        }
    }

    @Override
    public void onDiscoveryRequestChanged(@Nullable MediaRouteDiscoveryRequest request) {
        super.onDiscoveryRequestChanged(request);
        if (request == null || !request.isActiveScan() || !request.isValid()) {
            stopScan();
            return;
        }
        if (!request.getSelector().hasControlCategory(IAppConstants.CATEGORY)) {
            Log.i(LOGTAG, "Not scanning for non remote playback");
            stopScan();
            return;
        } else {
            Log.i(LOGTAG, "Scanning...");
            mediarouter.addCallback(ChromecastRouteProviderService.SELECTOR, callback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
            return;
        }
    }

    void updateDescriptor() {
        final MediaRouteProviderDescriptor.Builder descriptor = new MediaRouteProviderDescriptor.Builder();
        for (Iterator iterator = routes.values().iterator(); iterator.hasNext(); ) {
            MediaRouter.RouteInfo routeinfo = (MediaRouter.RouteInfo) iterator.next();
            try {
                Bundle bundle = new Bundle();
                bundle.putBoolean("has_upsell", true);
                descriptor.addRoute(new MediaRouteDescriptor.Builder(routeinfo.getId(), routeinfo.getName())
                        .addControlFilter(controlFilter).setPlaybackStream(3)
                        .setDescription(routeinfo.getDescription())
                        .setEnabled(true).setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
                        .setVolumeHandling(1).setVolumeMax(100).setVolume(100)
                        .setExtras(bundle).build());
            } catch (Exception e) {
                throw new Error("wtf");
            }
        }

        getHandler().post(new Runnable() {
            @Override
            public void run() {
                setDescriptor(descriptor.build());
            }
        });

    }

    void stopScan() {
        Log.i(LOGTAG, "Stopping scan...");
        try {
            MediaRouter.getInstance(getContext()).removeCallback(callback);
            return;
        } catch (Exception exception) {
            return;
        }
    }

    class CastCallBack extends MediaRouter.Callback {
        void check(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
            Log.i(LOGTAG, new StringBuilder().append("Checking route ").append
                    (routeinfo.getName()).toString());
            CastDevice device = CastDevice.getFromBundle(routeinfo.getExtras());
            if (routeinfo.matchesSelector(ChromecastRouteProviderService.SELECTOR)
                    && device != null && device.isOnLocalNetwork()) {
                routes.put(routeinfo.getId(), routeinfo);
                updateDescriptor();
                return;
            } else {
                return;
            }
        }

        public void onRouteAdded(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
            super.onRouteAdded(mediarouter, routeinfo);
            check(mediarouter, routeinfo);
        }

        public void onRouteChanged(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
            super.onRouteChanged(mediarouter, routeinfo);
            check(mediarouter, routeinfo);
        }

        public void onRouteRemoved(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
            super.onRouteRemoved(mediarouter, routeinfo);
            if (routeinfo.matchesSelector(ChromecastRouteProviderService.SELECTOR)) ;
        }

    }
}

}

like image 327
ingsaurabh Avatar asked Jan 13 '16 15:01

ingsaurabh


1 Answers

Ok finally I found answer on my own,

Problem is when any provider is selected it's not added using onRouteAdded why? I really dont understand google logic

So the solution is to unselect the router when you want or better select default route when so that your route is released

MediaRouter.getInstance(this).getDefaultRoute().select();

But again 1 out of 10 times it will not work

Hope will help someone

like image 140
ingsaurabh Avatar answered Oct 21 '22 00:10

ingsaurabh