Обход ограничений A2DP и HFP в Android Pre-HoneyComb

1

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

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

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

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

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

  • 0
    Я не думаю, что API-интерфейсы Honeycomb и Ice Cream Sandwich позволяют программно подключаться к аудио-приемникам A2DP или HFP. Глядя на документацию, я ничего не вижу, и, глядя на код, кажется, что эти методы скрыты. И, поскольку конструктор является областью действия пакета, вы не можете получить ссылку, если не используете прослушиватель службы и, следовательно, не можете вызывать их даже при использовании скрытых API. Пожалуйста, дайте мне знать, если я ошибаюсь в этом, поскольку я пытаюсь сделать что-то подобное.
  • 0
    извините за опоздание. Вы правы, они на самом деле не дают вам доступ к аудио приемнику. HC и ICS просто предлагают прокси-объект, позволяющий уведомлять вас, когда это так или нет. Кажется, единственный способ добиться того, что меня интересовало, - это вывод звука только при подключенном A2DP.
Теги:
bluetooth
a2dp

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, просто вызовите a2dp.connectSink(btDevice) или a2dp.connect(btDevice), если ваш SDK между 11 и 16.

Он не работает на Android 4.2 из-за полностью измененного стека Bluetooth.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню