1

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

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

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

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

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

4

1 回答 1

0

实际上,Android 并没有官方 API 来连接 a2dp 设备。

但是您可以使用反射来访问隐藏的类。我在我的项目中使用了这种方式,它适用于 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 < 11,如果您的 SDK 在 11 和 16 之间,只需调用a2dp.connectSink(btDevice)a2dp.connect(btDevice) 。由于蓝牙堆栈完全改变

,它在 Android 4.2 上不起作用。

于 2013-02-07T14:59:30.713 回答