号试图写入一个Android应用程序来处理,这将不会是溶液。至少如果你想使用A2DP Sink
角色。
事实上,正如你所提到的,Android并没有实现对BlueZ
(Android使用的蓝牙堆栈直到Jelly Bean 4.1)关于A2DP sink
功能的API调用。你必须自己实现它们。我会尽力引导你,因为我也有兴趣在过去做我的自我。
默认情况下,支持蓝牙的Android设备将自己宣传为A2DP source
设备。您必须首先更改此设置,以便附近的设备可以将您的设备识别为接收器。要做到这一点,你必须修改audio.conf文件(usally位于的/ etc /蓝牙/),并确保Enable
键存在和价值Source
连接到这个键,所以你会得到的东西,如:
Enable=Source
重启,附近的设备现在应该认识到您的设备作为A2DP sink
。
现在当一个A2DP信号源设备开始向您的手机传输音频时,您将不得不与BlueZ进行互动以做出适当反应。
Android和BlueZ正在通过D-BUS
互相交谈。事实上,Android连接到DBUS_SYSTEM通道,并收听每个BlueZ广告,如事件,文件描述符...
我记得我已经成功地使用原生应用程序绑定到这个d总线通道并获得访问BlueZ发布的各种活动。使用BlueZ API可用here作为参考,这相对容易实现。如果你这样做,你将不得不构建一个本地应用程序(C/C++)并为你的平台编译它。您必须能够使用Android NDK
执行此操作。
如果您觉得难以使用D-BUS
,您可以试试我刚发现的这个Java库,它为您处理与D-BUS的通信:http://jbluez.sourceforge.net/。我从来没有用过它,但在我看来这是值得一试的。
您真正需要做的是找出A2DP源设备何时与手机配对以及何时开始流式传输音乐。您可以通过D-BUS检索这些事件。一旦有人尝试传送音乐,您需要告诉BlueZ您的本机应用程序将处理它。有一个很好的文档解释了你应该处理的事件流程。该文档可以访问here。您感兴趣的部分来自第7页。在给定示例中的接收器应用程序是PulseAudio
,但它也可能是您的应用程序。
当你打电话给org.bluez.MediaTransport.Acquire
方法时,BlueZ会给你一个UNIX套接字。读取此套接字将为您提供当前由远程设备传输的数据。但是我记得一位在BlueZ堆栈上工作的人告诉我,在这个插座上读取的数据不是PCM纯音频,而是编码的音频内容。数据通常以称为SBC
(低复杂度子带编码)的格式编码。
解码SBC不是很困难,你可以找到一个解码器 right here。
最终的步骤是将PCM音频转发到扬声器。
为了防止您陷入困境,并为了以更简单的方式测试您的应用程序,您可以使用应该在Android系统上可用的d-bus
二进制文件。他位于/system/bin。
快速测试,你可以做的任何事情之前作出上述可能是:
获取设备列表:
的dbus-发送--system --dest = org.bluez --print -reply/ org.bluez.Manager.GetProperties
这将返回适配器数组及其路径。一旦你有了这些路径,你可以检索与你的适配器配对的所有蓝牙设备的列表。
获得配对的设备:
DBUS-发送--system --print回复--dest = org.bluez /组织/的bluez/{PID}/hci0 org.bluez.Adapter .GProProperties
这给出了设备阵列字段中配对设备的列表。
一旦你有蓝牙适配器配对的设备列表,你可以知道它是否连接到AudioSource接口。
获取连接到接口的AudioSource设备:
DBUS-发送--system --print回复--dest = org.bluez /组织/的bluez/{PID}/hci0/dev_XX_XX_XX_XX_XX_XX org.bluez.AudioSource.GetProperties org.bluez.Manager.GetProperties
希望这有助于。
嘿约翰尼,到目前为止没有什么进展? ;) – Nippey 2013-12-13 09:44:34
嘿!任何进展? – dpaksoni 2017-05-11 05:45:34