标签: mediarouter

如何可靠地获取和检测 Android 上活动音频路由的更改?

我有一个功能,我需要获取系统活动音频输出设备的当前检测开关。就像是:

  • 运行应用程序 -> 获取当前设备(可能是嵌入式扬声器)
  • 连接蓝牙扬声器 -> 检测开关到蓝牙扬声器
  • 连接音频插孔 -> 检测从蓝牙扬声器到音频插孔的开关

在我看来,这应该有一个 API,但似乎有几个。最有意义的一个似乎是,MediaRouter但它有两个大问题阻止我如上所述使用它:

  • 至少在 2 种情况下,它将错误的设备作为活动路由获取,而在其他情况下,它根本没有检测到路由切换。有关这方面的详细信息,请查看我在 google 问题跟踪器上打开的票证
  • 我需要有关当前活动输出设备的某些信息,最重要的是通用标识符。对于蓝牙设备,Complete Local Name可用于此目的,可从BluetoothDevice类型获得,但不能从MediaRouter. 相反,MediaRouter使一个productName可用,有时可以是蓝牙设备的别名,而不是静态名称。

我已经放弃了这个 API 并继续寻找其他解决方案,如果有人认为有办法解决上述问题,请告诉我,最重要的是第一个。我会注意到我同时使用了android.media.MediaRouterandroidxone,它们都有这些问题。

我现在正在利用其他 API 的组合。它有效,但它远非可接受的解决方案:

  • 使用AudioManager.registerAudioDeviceCallback(object : AudioDeviceCallback)非蓝牙设备检测(AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER))。当添加或删除这些设备中的任何一个时,我会收到回调,然后我可以检查是否存在有线类型设备,那么它在 100% 的时间都是活动的,如果不是,则嵌入式类型是活动的。这有点hacky,但它有效。

  • 更有趣的是,为了检测蓝牙输出设备,我使用了一个私有 API,Android 本身在设置应用程序中使用它来显示当前的音频输出设备

    • BluetoothA2dp::class.java.getDeclaredMethod("getActiveDevice") 获取当前活动的输出设备。这是通过获取配置文件代理服务来完成的bluetoothAdapter.getProfileProxy
    • 为这个动作注册一个接收器,BluetoothA2dp::class.java.getField("ACTION_ACTIVE_DEVICE_CHANGED").get(null)以检测蓝牙有源音频设备的开关。

此解决方案有效,但也有一些限制:

  • 它们是明显的私有 API,易受突然变化和潜在中断的影响 …

android a2dp android-audiomanager android-bluetooth mediarouter

9
推荐指数
0
解决办法
906
查看次数

Android MediaRouter Volume事件

我希望在投射时实现Youtube应用程序中看到的音量变化,例如app是在后台还是在锁定屏幕上

像这样

private void createSession() {
    ComponentName receiver = new ComponentName(getPackageName(), RemoteReceiver.class.getName());
    mediaSession = new MediaSessionCompat(this, "PlayerService", receiver, null);
    mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
            MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
    mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
            .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1f)
            .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE)
            .build());
    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
        @Override
        public void onAudioFocusChange(int focusChange) {
            // Ignore
        }
    }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
    mediaSession.setActive(true);

    mediaRouter = MediaRouter.getInstance(this);
    mediaRouter.setMediaSessionCompat(mediaSession);
}
Run Code Online (Sandbox Code Playgroud)

现在我得到滑块就像上面的图像,它响应音量按钮,但我没有收到我的广播接收器的变化.

audio android mediarouter

6
推荐指数
1
解决办法
497
查看次数

使用 DisplayManager 或 MediaRouter 实现 Flutter 多屏

我正在 Flutter 中开发一个应用程序,该应用程序应该在具有两个屏幕的 POS上运行。它基本上是一个通过 HDMI 电缆连接到另一个屏幕的平板电脑。

我的问题是,我在屏幕一侧运行的任何内容也会出现在客户端的屏幕上,我需要隐藏它并显示其他内容(例如促销)。

我已经成功地使用Android 演示 API来使用它(它只能在 Android 上运行)。我在某处读到我也可以使用媒体路由器来实现它。

但我想做的是运行 Flutter 的两个引擎,每个显示器上一个,或者控制 Flutter 中每个显示器中显示的内容。问题是我没有找到任何关于如何在 Flutter 上执行此操作的库或有用的文章。

有人知道我将如何实现这一目标吗?如果我做不到,我将不得不使用原生 Android 创建一个全新的项目。

android display-manager flutter mediarouter presentation-api

2
推荐指数
1
解决办法
2377
查看次数