號試圖寫入一個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