如何在MediaRoute选择/取消选择事件上可靠地检测设备类型

时间:2014-05-07 23:22:02

标签: java android

我已经挖掘了Android源代码,发现每次发生音频路由事件时,AudioRoutesInfo对象都基于MediaRouter中的内部updateAudioRoutes方法:

      void updateAudioRoutes(AudioRoutesInfo newRoutes) {
                if (newRoutes.mMainType != mCurAudioRoutesInfo.mMainType) {
                    mCurAudioRoutesInfo.mMainType = newRoutes.mMainType;
                    int name;
                    if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
                            || (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
                        name = com.android.internal.R.string.default_audio_route_name_headphones;
                    } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
                        name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
                    } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
                        name = com.android.internal.R.string.default_media_route_name_hdmi;
                    } else {
                        name = com.android.internal.R.string.default_audio_route_name;
                    }
                    sStatic.mDefaultAudioVideo.mNameResId = name;
                    dispatchRouteChanged(sStatic.mDefaultAudioVideo);
                }

                final int mainType = mCurAudioRoutesInfo.mMainType;

                boolean a2dpEnabled;
                try {
                    a2dpEnabled = mAudioService.isBluetoothA2dpOn();
                } catch (RemoteException e) {
                    Log.e(TAG, "Error querying Bluetooth A2DP state", e);
                    a2dpEnabled = false;
                }

                if (!TextUtils.equals(newRoutes.mBluetoothName, mCurAudioRoutesInfo.mBluetoothName)) {
                    mCurAudioRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
                    if (mCurAudioRoutesInfo.mBluetoothName != null) {
                        if (sStatic.mBluetoothA2dpRoute == null) {
                            final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
                            info.mName = mCurAudioRoutesInfo.mBluetoothName;
                            info.mDescription = sStatic.mResources.getText(
                                    com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
                            info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                            sStatic.mBluetoothA2dpRoute = info;
                            addRouteStatic(sStatic.mBluetoothA2dpRoute);
                        } else {
                            sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.mBluetoothName;
                            dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
                        }
                    } else if (sStatic.mBluetoothA2dpRoute != null) {
                        removeRouteStatic(sStatic.mBluetoothA2dpRoute);
                        sStatic.mBluetoothA2dpRoute = null;
                    }
                }

                if (mBluetoothA2dpRoute != null) {
                    if (mainType != AudioRoutesInfo.MAIN_SPEAKER &&
                            mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) {
                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
                    } else if ((mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) &&
                            a2dpEnabled) {
                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false);
                    }


             }
        }

不幸的是,我发现的唯一暴露于MediaRouter回调中的设备类型的是设备的内部字符串资源名称(例如电话或耳机)。但是,你可以看到,这个AudioRoutesInfo对象引用了该设备是否是耳机,HDMI等。

有没有人找到解决方案来获取这些信息?我找到的最好方法是使用内部资源名称,这非常难看。上帝,如果他们只提供AudioRoutesInfo对象,就可以访问所有这些信息,而不必依赖资源黑客。

0 个答案:

没有答案