【问题标题】:Working around A2DP and HFP limitations of Android Pre-HoneyComb解决 Android Pre-HoneyComb 的 A2DP 和 HFP 限制
【发布时间】:2011-12-11 20:23:09
【问题描述】:

我正在研究一个有趣的项目,该项目涉及通过蓝牙为智能手机混合流式音频,从 android 开始,因为这是我最有经验的。我曾经在 Android 上使用过蓝牙一两次,根据我的经验了解到 pre-honeycomb API 不允许应用程序连接到 A2DP 或 HFP 音频接收器。我已经在 HTC EVO 上的 Ginger Bread 上尝试过这个,使用必要的 UUID 无济于事。

根据官方文档,截至API LEVEL 11,这现在是可能的,但我敢肯定,稍后将提供此 API 级别的唯一设备将是 Ice Cream Sandwich 设备,因为支持仅在 Honey 中开始梳子。我是一个完全的业余爱好者,所以我不太可能很快将我的手套戴在开发级冰淇淋三明治设备上。为以后的修订修改任何代码都不是问题,因为我现在只是想证明概念。

理想情况下,我想使用配对 A2DP 设备的输入/输出流直接读取和写入 PCM 数据。但是,如果我现在想这样做,我很可能不得不使用解决方法。

我的想法是使用 android 的 AudioRecordAudioTrack 类,据我了解,它们从麦克风读取音频输入并将音频输出推送到扬声器。现在在这两种情况下,当 A2DP 设备未连接时,这些结构将分别使用设备的麦克风和扬声器。但是,当连接 A2DP 或 HFP 设备时,我不知道系统现在是否会将这些结构分别设置为耳机的麦克风和扬声器的输入和输出。如果是这样,那么我可以有效地将其应用到我的代码中,并在以后对其进行调整,以利用 Ice Cream Sandwich 中的直接支持。

在这方面经验相对丰富的人是否认为这种方法可行?在我坐下来编写一些可能会浪费时间的代码之前,我宁愿知道是否有人成功了。

【问题讨论】:

  • 我认为 Honeycomb 和 Ice Cream Sandwich API 也不允许您以编程方式连接到 A2DP 或 HFP 音频接收器。是吗?查看文档,我什么也没看到,查看代码,似乎这些方法被隐藏了。而且,由于构造函数是包作用域,除非您使用服务侦听器,否则您无法获得引用,因此即使使用隐藏的 API 也无法调用它们。请让我知道我是否错了,因为我正在尝试做类似的事情。
  • 抱歉我的迟到了。你是对的,他们实际上也没有让你访问音频接收器。 HC 和 ICS 仅提供一个代理对象以允许通知您何时通知您。似乎完成我感兴趣的事情的唯一方法是仅在连接 A2DP 时输出音频。

标签: android bluetooth a2dp


【解决方案1】:

实际上,Android 没有用于连接 a2dp 设备的官方 API。

但是您可以使用反射来访问隐藏的类。我在我的项目中使用了这种方式,它适用于从 android 2.3 到 android 4.1。

首先,您需要获取 IBluetoothA2dp.aidl 文件并将其放入您的项目文件夹 src/com.android
接下来,使用以下方法获取IBluetoothA2dp接口:

private static IBluetoothA2dp getIBluetoothA2dp() {
    IBluetoothA2dp ibta = null;

    try {
        final Class serviceManager = Class.forName("android.os.ServiceManager");
        final Method getService = serviceManager.getDeclaredMethod("getService", String.class);
        final IBinder iBinder = (IBinder) getService.invoke(null, "bluetooth_a2dp");
        final Class iBluetoothA2dp = Class.forName("android.bluetooth.IBluetoothA2dp");
        final Class[] declaredClasses = iBluetoothA2dp.getDeclaredClasses();
        final Class c = declaredClasses[0];
        final Method asInterface = c.getDeclaredMethod("asInterface", IBinder.class);

        asInterface.setAccessible(true);
        ibta = (IBluetoothA2dp) asInterface.invoke(null, iBinder);
    } catch (final Exception e) {
        Log.e("Error " + e.getMessage());
    }
    return ibta;
}

如果您的 SDK a2dp.connectSink(btDevice) 或 a2dp.connect(btDevice) 如果您的 SDK 在 11 和 16 之间。
它不适用于 Android 4.2,因为蓝牙堆栈已完全改变。

【讨论】:

    猜你喜欢
    • 2013-09-22
    • 2012-02-24
    • 2012-12-13
    • 2011-10-02
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    相关资源
    最近更新 更多