ho creato un repo GitHub con un progetto di esempio che mostra il problema di seguito chiedo circa qui:
https://github.com/paulpv/audio-loopback/tree/simplified/src/com/twistpair/wave/experimental/loopback
(si prega di bastone w/il ramo “semplificata” e disprezzo il ramo “master”)Android startBluetoothSco non di partenza sco ma isBluetoothScoOn restituisce true
I due file principali sono:
- https://github.com/paulpv/audio-loopback/blob/simplified/src/com/twistpair/wave/experimental/loopback/MainActivity.java
- https://github.com/paulpv/audio-loopback/blob/simplified/src/com/twistpair/wave/experimental/loopback/AudioStateManager.java
Diniego: Attualmente sto solo usando un singolo Samsung Epic SPH-D700 esecuzione CyanogenMod 10 Jelly Bean per codificare e testare questo con. Non ho provato questo su altri dispositivi, ma forse questo potrebbe aiutare a impedirmi di tirare fuori i miei capelli e impazzire.
mi batto ricevendo Android Bluetooth SCO per affidabile start e stop e la cattura/riproduzione audio PER MESI!
Quando riesco ad accedere al telefono in modalità SCO, l'acquisizione e la riproduzione tramite AudioRecord e AudioTrack (rispettivamente) funzionano bene come documentato.
Il problema che sto avendo è che non riesco a far entrare in modo affidabile il telefono in modalità SCO!
Gli esempi su "The Internet" per utilizzare startBluetoothSco() e setBluetoothScoOn (true) sembrano tutti semplici e diretti, ma quando li utilizzo sul mio dispositivo non funzionano quasi mai in modo affidabile.
Ho creato la mia app di prova che non fa altro che avviare e arrestare SCO e non riesco nemmeno a farlo funzionare in modo affidabile!
Il mio codice ascolta BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED EXTRA_STATE==CONNECTED.
È possibile rilevare in modo affidabile quando un auricolare è connesso o disconnesso.
Durante il rilevamento di una connessione, il gestore chiama immediatamente startBluetoothSco().
A potrebbe giurare che almeno una volta questo ha calciato SCO_AUDIO_STATE
a C O
NNECTED, ma il 99% delle volte risulta solo in una transizione da DISCONNECTED->CONNECTING->DISCONNECTED
.
Qui è la mia uscita di registro annotato dalla mia GitHub campione app:
10-03 17:00:13.970: I/dalvikvm(29487): Debugger is active
10-03 17:00:14.158: I/System.out(29487): Debugger has connected
10-03 17:00:15.779: I/System.out(29487): waiting for debugger to settle...
10-03 17:00:15.978: I/System.out(29487): debugger has settled (1325)
mia app inizia w/auricolare Jawbone spento e aggiorna l'interfaccia utente ...
10-03 17:00:16.568: D/MainActivity(29487): updateScreen()...
10-03 17:00:16.572: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=false
. ..Un aggiornamento fatto
Trasmissione appiccicosa che mi dice l'attuale SCO_AUDIO_STATE ...
10-03 17:00:16.689: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.media.ACTION_SCO_AUDIO_STATE_UPDATED flg=0x10 (has extras) }
10-03 17:00:16.689: D/AudioStateManager(29487): extras={"android.media.extra.SCO_AUDIO_PREVIOUS_STATE"=2, "android.media.extra.SCO_AUDIO_STATE"=0}
10-03 17:00:16.689: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED
10-03 17:00:16.693: D/AudioStateManager(29487): ==> scoAudioStatePrevious=SCO_AUDIO_STATE_CONNECTING(2)
10-03 17:00:16.693: D/AudioStateManager(29487): ==> scoAudioState=SCO_AUDIO_STATE_DISCONNECTED(0)
10-03 17:00:16.693: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED: SCO_AUDIO_STATE_DISCONNECTED
... SCO_AUDIO_STATE corrente == SCOLLEGATO; previsto, poiché il mio auricolare è spento.
Il listener di eventi SCO disconnesso viene chiamato e aggiorna l'interfaccia utente con due messaggi send ...
10-03 17:00:16.693: I/MainActivity(29487): onAudioManagerScoAudioDisconnected()
10-03 17:00:16.755: D/libEGL(29487): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
10-03 17:00:16.787: D/libEGL(29487): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
10-03 17:00:16.791: D/libEGL(29487): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
10-03 17:00:16.888: D/OpenGLRenderer(29487): Enabling debug mode 0
10-03 17:00:16.912: D/MainActivity(29487): MSG_UPDATE_BLUETOOTH_INDICATION
10-03 17:00:16.912: D/MainActivity(29487): updateScreen()...
10-03 17:00:16.912: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=false
10-03 17:00:16.927: D/MainActivity(29487): MSG_UPDATE_AUDIO_OUTPUT_STREAM_TYPE
10-03 17:00:16.927: D/MainActivity(29487): updateScreen()...
10-03 17:00:16.931: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=false
... aggiornamento dell'interfaccia utente fatto
Dopo ~ 20 secondi accendo il mio auricolare Jawbone ...
10-03 17:00:37.572: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED flg=0x10 (has extras) }
10-03 17:00:37.583: D/AudioStateManager(29487): extras={"android.bluetooth.device.extra.DEVICE"=00:21:3C:00:3E:02, "android.bluetooth.profile.extra.PREVIOUS_STATE"=0, "android.bluetooth.profile.extra.STATE"=1}
10-03 17:00:37.587: D/AudioStateManager(29487): mReceiver: BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED
10-03 17:00:37.587: D/AudioStateManager(29487): ==> bluetoothDevice=00:21:3C:00:3E:02
10-03 17:00:37.587: D/AudioStateManager(29487): ==> bluetoothHeadsetStatePrevious=STATE_DISCONNECTED(0)
10-03 17:00:37.587: D/AudioStateManager(29487): ==> bluetoothHeadsetState=STATE_CONNECTING(1)
10-03 17:00:37.619: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED flg=0x10 (has extras) }
10-03 17:00:37.623: D/AudioStateManager(29487): extras={"android.bluetooth.device.extra.DEVICE"=00:21:3C:00:3E:02, "android.bluetooth.profile.extra.PREVIOUS_STATE"=1, "android.bluetooth.profile.extra.STATE"=2}
10-03 17:00:37.623: D/AudioStateManager(29487): mReceiver: BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED
10-03 17:00:37.623: D/AudioStateManager(29487): ==> bluetoothDevice=00:21:3C:00:3E:02
10-03 17:00:37.626: D/AudioStateManager(29487): ==> bluetoothHeadsetStatePrevious=STATE_CONNECTING(1)
10-03 17:00:37.626: D/AudioStateManager(29487): ==> bluetoothHeadsetState=STATE_CONNECTED(2)
Jawbone collegato; Il mio listener di eventi si chiama ...
10-03 17:00:37.626: I/MainActivity(29487): onBluetoothHeadsetConnected()
... vede che siamo in grado di SCO ...
10-03 17:00:37.626: D/AudioStateManager(29487): mAudioManager.isBluetoothScoAvailableOffCall()=true
... e auto-chiama startBluetoothSco()
ECCO DOVE È IL PROBLEMA! Perché questa chiamata a startBluetoothSco non risulta in SCO_AUDIO_STATE == CONNECTED?!?!
10-03 17:00:37.626: D/AudioStateManager(29487): startBluetoothSco()
10-03 17:00:37.626: I/AudioStateManager(29487): mAudioManager.startBluetoothSco();
mio listener di eventi finisce su w/a sendMessage per aggiornare l'interfaccia utente w/l'attuale stato di BT ...
10-03 17:00:37.646: D/MainActivity(29487): MSG_UPDATE_BLUETOOTH_INDICATION
10-03 17:00:37.650: D/MainActivity(29487): updateScreen()...
10-03 17:00:37.650: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=false
... aggiornamento dell'interfaccia utente fatta
Primo risultato da startBluetoothSco entra in ...
10-03 17:00:37.681: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.media.ACTION_SCO_AUDIO_STATE_UPDATED flg=0x10 (has extras) }
10-03 17:00:37.681: D/AudioStateManager(29487): extras={"android.media.extra.SCO_AUDIO_STATE"=2, "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"=0}
10-03 17:00:37.681: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED
10-03 17:00:37.685: D/AudioStateManager(29487): ==> scoAudioStatePrevious=SCO_AUDIO_STATE_DISCONNECTED(0)
10-03 17:00:37.685: D/AudioStateManager(29487): ==> scoAudioState=SCO_AUDIO_STATE_CONNECTING(2)
... spostato da ESTRATTO alla COLLEGAMENTO
Secondo risultato da startBluetoothSco entra in gioco ...
10-03 17:00:37.759: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.media.ACTION_SCO_AUDIO_STATE_UPDATED flg=0x10 (has extras) }
10-03 17:00:37.763: D/AudioStateManager(29487): extras={"android.media.extra.SCO_AUDIO_STATE"=0, "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"=2}
10-03 17:00:37.763: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED
10-03 17:00:37.763: D/AudioStateManager(29487): ==> scoAudioStatePrevious=SCO_AUDIO_STATE_CONNECTING(2)
10-03 17:00:37.763: D/AudioStateManager(29487): ==> scoAudioState=SCO_AUDIO_STATE_DISCONNECTED(0)
10-03 17:00:37.763: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED: SCO_AUDIO_STATE_DISCONNECTED
... spostato di connettersi a SCOLLEGATO
lo farei mi aspettavo che SCO passasse da CONNECTING a CONNECTED!
mio listener di eventi viene chiamato e aggiorna l'interfaccia utente w/due SendMessages ...
10-03 17:00:37.763: I/MainActivity(29487): onAudioManagerScoAudioDisconnected()
10-03 17:00:37.767: D/MainActivity(29487): MSG_UPDATE_BLUETOOTH_INDICATION
10-03 17:00:37.767: D/MainActivity(29487): updateScreen()...
10-03 17:00:37.767: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=false
10-03 17:00:37.783: D/MainActivity(29487): MSG_UPDATE_AUDIO_OUTPUT_STREAM_TYPE
10-03 17:00:37.783: D/MainActivity(29487): updateScreen()...
10-03 17:00:37.783: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=false
... aggiornamento dell'interfaccia utente fatta
Aspetto ~ 20 secondi per SCO collegati ma non viene mai.
Premere il pulsante "startBluetoothSco" della mia app.
NOTA CHE QUESTO RISULTA ESATTAMENTE NELLO STESSO CHIAMATA per startBluetoothSco() AT 17:00:37.626
10-03 17:01:01.689: D/AudioStateManager(29487): startBluetoothSco()
10-03 17:01:01.689: I/AudioStateManager(29487): mAudioManager.startBluetoothSco();
primo risultato da startBluetoothSco entra in gioco ...
10-03 17:01:01.708: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.media.ACTION_SCO_AUDIO_STATE_UPDATED flg=0x10 (has extras) }
10-03 17:01:01.712: D/AudioStateManager(29487): extras={"android.media.extra.SCO_AUDIO_STATE"=2, "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"=0}
10-03 17:01:01.712: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED
10-03 17:01:01.712: D/AudioStateManager(29487): ==> scoAudioStatePrevious=SCO_AUDIO_STATE_DISCONNECTED(0)
10-03 17:01:01.712: D/AudioStateManager(29487): ==> scoAudioState=SCO_AUDIO_STATE_CONNECTING(2)
... spostato da ESTRATTO alla COLLEGAMENTO
Qui è dove le cose sono diverse da quelle di auto-call di startBluetoothSco() a 17: 00: 37,626
Otteniamo un BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED evento ...
10-03 17:01:01.716: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED flg=0x10 (has extras) }
10-03 17:01:01.720: D/AudioStateManager(29487): extras={"android.bluetooth.device.extra.DEVICE"=00:21:3C:00:3E:02, "android.bluetooth.profile.extra.PREVIOUS_STATE"=10, "android.bluetooth.profile.extra.STATE"=11}
10-03 17:01:01.720: D/AudioStateManager(29487): mReceiver: BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
10-03 17:01:01.720: D/AudioStateManager(29487): ==> bluetoothDevice=00:21:3C:00:3E:02
10-03 17:01:01.720: D/AudioStateManager(29487): ==> bluetoothHeadsetAudioStatePrevious=STATE_AUDIO_DISCONNECTED(10)
10-03 17:01:01.720: D/AudioStateManager(29487): ==> bluetoothHeadsetAudioState=STATE_AUDIO_CONNECTING(11)
... spostato da ESTRATTO alla COLLEGAMENTO
Otteniamo un altro evento BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED ...
10-03 17:01:02.572: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED flg=0x10 (has extras) }
10-03 17:01:02.576: D/AudioStateManager(29487): extras={"android.bluetooth.device.extra.DEVICE"=00:21:3C:00:3E:02, "android.bluetooth.profile.extra.PREVIOUS_STATE"=11, "android.bluetooth.profile.extra.STATE"=12}
10-03 17:01:02.576: D/AudioStateManager(29487): mReceiver: BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
10-03 17:01:02.576: D/AudioStateManager(29487): ==> bluetoothDevice=00:21:3C:00:3E:02
10-03 17:01:02.576: D/AudioStateManager(29487): ==> bluetoothHeadsetAudioStatePrevious=STATE_AUDIO_CONNECTING(11)
10-03 17:01:02.580: D/AudioStateManager(29487): ==> bluetoothHeadsetAudioState=STATE_AUDIO_CONNECTED(12)
. ..moved from CONNECTING to CONNECTED
evento aggiorna l'interfaccia utente w/uno sendMessage
10-03 17:01:02.580: I/MainActivity(29487): onBluetoothHeadsetAudioConnected()
10-03 17:01:02.580: D/MainActivity(29487): MSG_UPDATE_BLUETOOTH_INDICATION
10-03 17:01:02.580: D/MainActivity(29487): updateScreen()...
10-03 17:01:02.583: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=true
... aggiornamento UI fatto (Per essere onesti, io non sono sicuro di quello che sta chiamando isBluetoothScoOn una seconda volta)
10-03 17:01:02.603: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=true
secondo risultato da startBluetoothSco entra in gioco ...
10-03 17:01:02.603: D/AudioStateManager(29487): onReceive: intent=Intent { act=android.media.ACTION_SCO_AUDIO_STATE_UPDATED flg=0x10 (has extras) }
10-03 17:01:02.607: D/AudioStateManager(29487): extras={"android.media.extra.SCO_AUDIO_STATE"=1, "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"=2}
10-03 17:01:02.607: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED
10-03 17:01:02.607: D/AudioStateManager(29487): ==> scoAudioStatePrevious=SCO_AUDIO_STATE_CONNECTING(2)
10-03 17:01:02.607: D/AudioStateManager(29487): ==> scoAudioState=.SCO_AUDIO_STATE_CONNECTED(1)
10-03 17:01:02.607: D/AudioStateManager(29487): android.media.ACTION_SCO_AUDIO_STATE_UPDATED: SCO_AUDIO_STATE_CONNECTED
... spostato da CONNECTING a CONNECTED
FINALMENTE!
mio listener di eventi viene chiamato e aggiorna l'interfaccia utente w/due SendMessages ...
10-03 17:01:02.611: I/MainActivity(29487): onAudioManagerScoAudioConnected()
10-03 17:01:02.630: D/MainActivity(29487): MSG_UPDATE_BLUETOOTH_INDICATION
10-03 17:01:02.630: D/MainActivity(29487): updateScreen()...
10-03 17:01:02.634: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=true
10-03 17:01:02.650: D/MainActivity(29487): MSG_UPDATE_AUDIO_OUTPUT_STREAM_TYPE
10-03 17:01:02.650: D/MainActivity(29487): updateScreen()...
10-03 17:01:02.650: D/AudioStateManager(29487): mAudioManager.isBluetoothScoOn()=true
... aggiornamento dell'interfaccia utente fatto
Tutto (questa volta) funziona quando " manualmente "avvia SCO dopo un po 'di tempo, ma non se avvio automaticamente SCO immediatamente dopo aver collegato un auricolare.
A peggiorare le cose, quando le cose non funzionano come previsto Vedo strano comportamento nella SCO afferma:
- Ritardare l'startBluetoothSco() per 3-5 secondi ragionevoli sembra fare alcuna differenza . Non ho provato a ritardarlo più di 5 secondi. Aspettare più di 5 secondi prima che l'audio inizi a scorrere verso l'auricolare BT è ridicolo.
- volte chiamando isBluetoothScoOn() restituisce vero, anche se non ho mai ricevuto un evento di trasmissione dal momento che l'ultimo stato DISCONNECTED dicendo quello stato cambiato in Connesso.
- volte "manualmente" chiamando startBluetoothSco() dall'interfaccia utente non fa nulla, come se SCO è già acceso, ma non ho mai ricevuto alcun evento di trasmissione dal momento che l'ultimo stato DISCONNECTED dicendo quello stato cambiato in Connesso.
- Prova di aprire o audiotrack AudioRecord risultati in alcun suono (questo stesso codice funziona bene quando SCO non ha un comportamento anomalo es. Il problema è stato SCO, non l'AudioTrack/AudioRecord chiamate).
- La chiamata a stopBluetoothSco() non comporta la visualizzazione di uno stato di evento DISCONNECTED.
- setBluetoothScoOn (false/true) non fa alcuna differenza. Ad essere onesti, non capisco la differenza in "startBluetoothSco()/stopBluetoothSco()" apparentemente ridondante e "setBluetoothScoOn (booleano)". Quando le cose funzionano, la mia chiamata startBluetoothSco() restituisce isBluetoothScoOn() restituendo true, facendomi pensare che non ho bisogno di chiamare setBluetoothScoOn (true).
- Il riavvio del telefono non fa alcuna differenza.
- Il riavvio dell'auricolare non fa differenza.
- Il passaggio a un altro auricolare non fa alcuna differenza.
- A volte l'auricolare perde il suo accoppiamento e deve essere nuovamente associato.
Dato il track record di Google/Android sul supporto Bluetooth, molto poco di questo mi sorprende.
Qualcuno può per favore mi ha messo fuori dalla mia miseria e sicuramente spiegare come avviare e arrestare il bluetooth SCO in Android in modo affidabile?
PS: C'è un canale ufficiale ad aumentare i problemi come questo [w/Google? Samsung?]? Oppure, StackOverflow è la mia migliore possibilità di trovare una risposta effettiva?
Ho eseguito questo stesso codice su un RAZR Motorola che esegue ICS e ha i risultati esatti o peggiori. Su questo Motorola RAZR non riesco nemmeno a "manualmente" avviare startBluetoothSco() per andare da SCO_AUDIO_STATE_CONNECTING-> SCO_AUDIO_STATE_CONNECTED. – swooby
L'ho provato anche con un auricolare Samsung HM1700 e un auricolare Jawbone non-A2DP. Telefoni diversi, cuffie diverse; Risultati esatti [o peggiori]. :( – swooby
Ho il problema esatto, posso solo dirti che ho un codice simile al tuo che funziona su Samsung Galaxy Mini con Gingerbread e funziona ma lo stesso codice non funziona affatto su Jellybean. – Ahmed