android – Chromecast MediaRouteProviderService

我有一个奇怪的问题,我正在为chromecast创建mediaprovider使用以下代码,第一次工作正常,显示设备列表,一次选择我使用router.selectRoute(routeinfo);
但是一旦我退出应用程序,此代码无法找到Chromecast设备,那么当我从运行的应用程序中删除应用程序时,该代码如何工作,再次显示设备.

如果没有选择设备,并且使用后退键退出应用程序,则该代码也可以正常工作

那么我在这里做错了什么?当我的应用程序退出时,我认为是资源不会被清除.

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);
        }

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

    }
}

}

解决方法

好的,我终于找到了我自己的答案,

问题是什么时候任何提供者被选中,它没有添加使用onRouteAdded为什么?我真的不明白谷歌的逻辑

所以解决方案是当您想要或更好地选择认路由以使路由被释放时取消选择路由器

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

但是再一次10次之中它将无法工作

希望会帮助某人

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...