在Android中通过蓝牙接收audio

我想创build一个能够接收audiostream的Android应用程序。 我想使用A2DPconfiguration文件,但似乎Android不支持A2DP接收器。 看起来好像有很多人在为这个问题寻找解决scheme。 但是接收一个普通的比特stream,然后在应用程序中将数据转换为audio呢? 我正在考虑通过RFCOMM(SPP蓝牙configuration文件)接收PCM或Mp3数据stream,然后使用AudioTrack进行播放。

首先,如何通过RFCOMM在Android手机上接收比特stream? 是否有可能通过RFCOMM作为PCM或Mp3stream接收比特stream?

其次,如果无法通过RFCOMM接收比特stream作为PCM或Mp3stream,那么如何将接收到的比特stream转换为audio?

第三,如何将接收到的数据转换为audio并同时“实时”播放audio? 我可以使用onDataReceived吗?

要清楚,我不感兴趣的使用A2DPconfiguration文件! 我想通过RFCOMM(SPP蓝牙configuration文件)stream式传输数据。 接收到的数据stream将以PCM或Mp3格式。 我想写自己的应用程序,但如果有人知道一个应用程序来解决这个问题,我会很高兴听到! 我正在使用Android 2.3姜饼。

/约翰尼

Solutions Collecting From Web of "在Android中通过蓝牙接收audio"

不。试图编写一个处理这个问题的Android应用程序将不是解决scheme。 至less如果你想使用A2DP Sinkangular色。

事实上,正如你所提到的,Android并没有实现对BlueZ (蓝牙堆栈,直到Jelly Bean 4.1使用的蓝牙堆栈)的A2DP sinkfunction的API调用。 你必须自己实现它们。 我会尽力引导你,因为我也有兴趣在过去做我自己的事情。

默认情况下,支持蓝牙的Android设备将自己宣传为A2DP source设备。 您必须先更改,以便附近的设备可以将您的设备识别为接收器。 要做到这一点,你必须修改audio.conf文件(通常位于/ etc / bluetooth / ),并确保Enable键存在,并且值被附加到这个键,所以你会得到像这样的东西:

 Enable=Source 

重新启动后,附近的设备现在应该可以将您的设备识别为A2DP sink

现在,当A2DP信号源设备开始向您的手机传输audio时,您必须与BlueZ进行交互才能做出适当的反应。

Android和BlueZ正在通过D-BUS相互交谈。 事实上,Android连接到DBUS_SYSTEM通道,并侦听每个BlueZ广告,如事件,文件描述符…

我记得我已经成功地使用本地应用程序绑定到这个d-bus频道,并且能够访问BlueZ发布的各种事件。 这是相对容易实现使用作为参考,在这里可用的BlueZ API。 如果你这样做,你将不得不build立一个本地应用程序(C / C ++)并为你的平台进行编译。 你必须能够使用Android NDK来做到这一点。

如果你觉得使用D-BUS很困难,你可以尝试一下我刚刚发现的这个Java库,它为你处理与D-BUS的通信: http : //jbluez.sourceforge.net/ 。 我从来没有使用过,但在我看来,这是值得一试的。

你真正需要做的是找出A2DP源设备何时与你的手机配对,何时开始stream式传输音乐。 您可以通过D-BUS检索这些事件。 一旦有人尝试传送音乐,您需要告诉BlueZ您的本机应用程序将处理它。 有一个很好的文档解释了你应该处理的事件stream程。 这个文件可以在这里find 。 你感兴趣的部分来自第7页。在给定的例子中的接收器应用程序是PulseAudio但它也可以是你的应用程序。

当你调用org.bluez.MediaTransport.Acquire方法的时候,BlueZ会给你一个UNIX套接字。 读取此套接字将为您提供远程设备当前stream式传输的数据。 但是我记得一个在BlueZ堆栈上工作的人告诉我,在这个sockets上读取的数据不是PCM纯audio,而是编码的audio内容。 数据通常以称为SBC (低复杂度子带编码)的格式编码

解码SBC不是很困难,你可以在这里find一个解码器。

最终的步骤是将PCMaudio转发到您的扬声器。

为了防止你陷入困境,为了以更简单的方式testing你的应用程序,你可以使用应该在你的Android系统上可用的d-bus二进制文件。 他位于/ system / bin

在做以上任何事情之前,您可以做的快速testing可能是:

获取设备列表:

dbus-send –system –dest = org.bluez –print-reply / org.bluez.Manager.GetProperties

这将返回适配器数组及其path。 一旦你有这些path(S),你可以检索与适配器(S)配对的所有蓝牙设备的列表。

获取配对的设备:

dbus-send –system –print-reply –dest = org.bluez / org / bluez / {pid} / hci0 org.bluez.Adapter.GetProperties

这给你在设备数组字段中的配对设备列表。

一旦你有蓝牙适配器配对的设备列表,你可以知道它是否连接到audio源接口。

获取连接到AudioSource界面的设备:

dbus-send –system –print-reply –dest = org.bluez / org / bluez / {pid} / hci0 / dev_XX_XX_XX_XX_XX_XX org.bluez.AudioSource.GetProperties org.bluez.Manager.GetProperties

希望这可以帮助。

另一个解决方法是使用HandsFreeProfile。

在Android中,BluetoothHeadset正在努力。 等到状态更改为BluetoothHeadset.STATE_AUDIO_CONNECTED。

那么你可以从蓝牙耳机录制audio。

  mMediaRecorder = new MediaRecorder(); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mMediaRecorder.setOutputFile(mFilename); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mMediaRecorder.start(); 

[无关,但作品]这黑客服务只通过WIFI热点的MP3stream(我用它只有AUXinput我的车):

  1. 安装应用程序AirSong ,
  2. 打开wifi热点,
  3. 将其他设备连接到该热点,
  4. 从设备的浏览器访问192.168.43.1:8088,然后开机。

(想知道为什么只有“192.168.43.1”?因为那是连接到Android Hotspot的任何设备的默认网关)

audio.conf似乎在Android 4.2.2中缺less?

要通过rfcomm接收pcmaudiostream,可以使用代码stream作为提示说明( 读取C中的audio文件,并通过蓝牙转发以在Androidaudio轨道中播放 ),并进行更改。 在从44100到22050的初始化时更改频率

 AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,22050,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_8BIT,10000, AudioTrack.MODE_STREAM); 

注意:这stream媒体仍然包含一些噪音,但你的

“通过RFCOMM(SPP蓝牙configuration文件)接收PCM数据stream,然后使用AudioTrack进行播放”。

将工作。