Обход ограничений A2DP и ​​HFP в Android Pre-HoneyComb - PullRequest
1 голос
/ 12 декабря 2011

Я исследую интересный проект, включающий микширование потокового аудио через Bluetooth для смартфонов, начиная с Android, так как это то, с чем у меня больше всего опыта. Я работал с Bluetooth на Android один или два раза и по своему опыту узнал, что предварительный сотовый API не позволяет приложениям подключаться к приемникам звука A2DP или HFP. Я уже пробовал это на Ginger Bread на HTC EVO, используя необходимый UUID безрезультатно.

Согласно официальной документации, по состоянию на API LEVEL 11 это теперь возможно, но я уверен, что единственными устройствами, которые будут предлагать этот уровень API, будут устройства Ice Cream Sandwich позже, так как поддержка началась только в Honey Comb. Я абсолютный любитель, поэтому вряд ли я получу свои перчатки на устройстве Ice Cream Sandwich для разработчиков. Адаптация любого кода для более поздних ревизий не будет проблемой, так как я просто пытаюсь доказать концепцию прямо сейчас.

В идеале я хотел бы использовать потоки ввода / вывода сопряженного устройства A2DP для непосредственного чтения и записи данных PCM. Однако, если я хочу сделать это сейчас, мне, скорее всего, придется использовать обходной путь.

Моя идея состоит в том, чтобы использовать классы AudioRecord и AudioTrack для Android, которые, в соответствии с моим пониманием, считывают аудиовход с микрофона и выводят аудиосигнал на динамик. Теперь в обоих случаях, когда устройство A2DP не подключено, эти структуры будут использовать микрофон и динамик устройства соответственно. Однако, когда подключено устройство A2DP или HFP, я не знаю, настроит ли система теперь эти структуры соответствующим входом и выходом на микрофон и динамик гарнитуры. Если так, то я мог бы эффективно встроить это в свой код и позже адаптировать его, чтобы воспользоваться прямой поддержкой Ice Cream Sandwich.

Кто-нибудь с относительно большим опытом в этой области считает, что этот подход будет работать? Я предпочел бы знать, если кто-нибудь добился успеха, прежде чем я сижу и пишу код, который потенциально может быть пустой тратой времени.

1 Ответ

0 голосов
/ 07 февраля 2013

На самом деле 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, просто позвоните <strong>a2dp.connectSink (btDevice) или a2dp.connect (btDevice) , если ваш SDK находится в диапазоне от 11 до 16. Не работает на Android 4.2 из-за полностью измененного стека Bluetooth.

...