Ответ 1
Нет. Попытка написать приложение для Android, которое обрабатывает это, не будет решением. По крайней мере, если вы хотите использовать роль A2DP Sink
.
Дело в том, что Android, как вы уже упоминали, не выполняет вызовы API BlueZ
(стек bluetooth Android использует до Желе Bean 4.1) относительно возможностей A2DP Sink
. Вы должны реализовать их самостоятельно. Я попытаюсь направить вас, поскольку мне также было интересно это сделать в ближайшем прошлом.
Ваш Android-устройство с поддержкой bluetooth рекламирует себя как устройство A2DP source
по умолчанию. Сначала вы должны изменить это, поэтому поблизости устройства могут распознать ваше устройство как приемник. Для этого вы должны изменить файл audio.conf (обычно расположенный в /etc/bluetooth/) и убедиться, что существует клавиша Enable
и значение Source
прикрепляется к этому ключу, поэтому вы получите что-то вроде:
Enable=Source
Перезагрузите, находящиеся поблизости устройства должны теперь распознать ваше устройство как A2DP Sink
.
Теперь вам нужно будет взаимодействовать с BlueZ, чтобы реагировать соответствующим образом, когда исходное устройство A2DP начнет передавать аудио на ваш телефон.
Android и BlueZ разговаривают друг с другом через D-BUS
. Фактически, Android подключается к каналу DBUS_SYSTEM и слушает каждую рекламу BlueZ, такую как события, файловые дескрипторы...
Я помню, как успешно связал себя, используя собственное приложение к этому каналу d-bus и получил доступ к различным событиям, которые BlueZ публиковал. Это относительно легко достичь с помощью ссылки, BlueZ API доступен здесь. Если вы пойдете так, вам придется создать собственное приложение (C/С++) и скомпилировать его для вашей платформы. Вы должны сделать это, используя Android NDK
.
Если вам трудно использовать D-BUS
, вы можете попробовать эту библиотеку Java, которую я только что нашел, которая обрабатывает связь с D-BUS для вас: http://jbluez.sourceforge.net/. Я никогда не использовал его, но, на мой взгляд, стоит попробовать.
Что вам действительно нужно сделать, так это узнать, когда исходное устройство A2DP сопряжено с вашим телефоном и когда он начинает передавать музыку. Вы можете получить эти события через D-BUS. Когда кто-то попытается передать музыку, вам нужно сказать BlueZ, что ваше родное приложение будет обрабатывать его. Существует довольно хороший документ, который объясняет поток событий, которые вы должны использовать для этого. Этот документ доступен здесь. Часть, которую вас интересует, приведена на странице 7. Приложение-приемник в данном примере - PulseAudio
, но оно также может быть вашим приложением.
BlueZ отправит вам сокет UNIX, когда вы вызовете метод org.bluez.MediaTransport.Acquire
. Чтение этого сокета даст вам данные, которые в настоящее время передаются удаленным устройством. Но я помню, что парень, работающий над стеклом BlueZ, сказал, что данные, прочитанные в этом сокете, не являются чистым звуком PCM, а закодированным аудиоконтентом. Данные обычно кодируются в формате под названием SBC
(низкополосное кодирование подсетей).
Декодирование SBC не очень сложно, вы можете найти декодер здесь.
Конечным шагом будет пересылка звука PCM в ваши динамики.
Чтобы вы не застряли и чтобы легче протестировать ваше приложение, вы можете использовать двоичный файл D-BUS
, который должен быть доступен в вашей системе Android. Он находится в /system/bin.
Быстрые тесты, которые вы можете сделать, прежде чем делать что-либо из вышеизложенного, могут быть:
Получить список устройств:
dbus-send --system --dest = org.bluez --print-reply/ org.bluez.Manager.GetProperties
Возвращает массив адаптеров со своими путями. После того, как у вас есть эти пути, вы можете получить список всех Bluetooth-устройств в паре с вашим адаптером.
Получить сопряженные устройства:
dbus-send --system --print-reply --dest = org.bluez /org/bluez/ {pid}/hci0 org.bluez.Adapter.GetProperties
Это дает вам список спаренных устройств в поле "Устройства".
Как только у вас есть список устройств, соединенных с вашим адаптером Bluetooth, вы можете узнать, подключен ли он к интерфейсу AudioSource.
Получить устройства, подключенные к интерфейсу AudioSource:
dbus-send --system --print-reply --dest = org.bluez /Орг/BlueZ/{PID}/hci0/dev_XX_XX_XX_XX_XX_XX org.bluez.AudioSource.GetProperties org.bluez.Manager.GetProperties
Надеюсь, что это поможет.