解决Android Pre-HoneyComb的A2DP和HFP限制

时间:2011-12-11 20:23:09

标签: android bluetooth a2dp

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

根据官方文档,从API LEVEL 11开始,现在已经可以了,但我很确定将来提供此API级别的唯一设备将是Ice Cream Sandwich设备,因为仅支持启动在蜂蜜梳子。我是一个非常业余的人,所以我不太可能很快将我的手套放在开发级冰淇淋三明治设备上。调整任何代码以供日后修改都不会成为问题,因为我现在只想证明概念。

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

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

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

1 个答案:

答案 0 :(得分: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上运行