AudioManager.startBluetoothSco () se bloquea en Android Lollipop
Al realizar una llamada a AudioManager.startBluetoothSCO () mientras se orienta al API nivel 18 o superior en el manifiesto, la documentación indica que se establece una conexión de audio sin procesar y si se utiliza la API de orientación 17 o inferior a una llamada de voz virtual.
Hasta el nivel API 20 (Android L Preview) esto funcionó bien, dirigiéndose a cualquier API. Sin embargo, al usar la última versión de Android Lollipop LPX13D y apuntar el API de nivel 18 o superior, obtengo un bloqueo con el siguiente seguimiento de pila:
- Cómo borrar mediante programación la caché de nombres de Bluetooth en Android?
- Programa se bloquea en ObjectInputStream método readObject.
- OnServicesDiscovered nunca se llama mientras se conecta a GATT Server
- ¿Cómo puedo recibir mensajes pendientes con la API cercana de google?
- IOS 7 Multipeer Connectivity es compatible con Android Wi-Fi Direct?
E / AndroidRuntime (31705): Causado por: java.lang.NullPointerException: Intenta invocar el método virtual 'java.lang.String android.bluetooth.BluetoothDevice.getAddress ()' en una referencia de objeto nulo E / AndroidRuntime (31705): at Android.os.Parcel.readException (Parcel.java:1546) E / AndroidRuntime (31705): en android.os.Parcel.readException (Parcel.java:1493) E / AndroidRuntime (31705): en android.media.IAudioService $ Stub $ Proxy.startBluetoothSco (IAudioService.java:1587) E / AndroidRuntime (31705): en android.media.AudioManager.startBluetoothSco (AudioManager.java:1468)
Si apunto el nivel API 17 o inferior en Android Lollipop todo funciona como se esperaba.
Creo que la fuente del problema reside en un cambio en el código de audio de Android que sucedió en el nivel 21 de la API en el archivo AudioService.java línea 2392:
public void startBluetoothSco(IBinder cb, int targetSdkVersion) { int scoAudioMode = (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? SCO_MODE_VIRTUAL_CALL : SCO_MODE_UNDEFINED; startBluetoothScoInt(cb, scoAudioMode); }
Parece que SCO_MODE_UNDEFINED debería ser SCO_MODE_RAW. Si miras a través del archivo, puedes ver que SCO_MODE_RAW está comprobado en unos pocos lugares, pero nunca se transmite en ningún lugar.
¿Alguien más está experimentando este accidente? ¿Alguien sabe de una solución mejor que degradar el SDK de destino a 17? Si no es así, ¿podría por favor marcar el informe de fallo que presenté con Google para aumentar la posibilidad de que se vea 🙂
- Cómo borrar el búfer de InputStream bluetooth
- Android BLE API: GATT Notificación no recibida
- Conexión automática a un dispositivo BLE conocido
- ¿Es el intercambio de archivos Bluetooth completamente seguro?
- Android bluetooth UUID que conecta APP a ANDROID
- La voz del auricular Bluetooth reconoce que no funciona
- Hacer Android BLE (Bluetooth LE) de forma estable
- Parámetros de conexión de baja energía de Bluetooth para Android, iOS y Win8
Como @xsveda escribió si no hay auriculares conectados, recibirá NPE en Lollipop.
Usted puede intentar comprobar la conexión del receptor de cabeza de bluetooth primero:
mAudioManager.isWiredHeadsetOn()
Como se describe el documento se isWiredHeadsetOn()
( doc link ) es depricated y utiliza sólo para comprobar es un auricular está conectado o no.
Y después de esto se puede utilizar la conexión startBluetoothSco()
. En cuanto a mí he utilizado este código:
Éste para el comienzo:
if(mAudioManager.isWiredHeadsetOn()) mAudioManager.startBluetoothSco();
Este para la parada:
if(mAudioManager.isBluetoothScoOn()) mAudioManager.stopBluetoothSco();
Espero eso ayude.
Después de unos días de desesperación he encontrado una solución sencilla:
startBluetoothSco()
lanza NPE sólo si no hay ningún dispositivo Bluetooth conectado para que pueda ser capturado e ignorado ya que no hay "nadie con quien hablar". Si, por ejemplo, un auricular BT está conectado, SCO se inicia correctamente y la reproducción está funcionando.
Por ahora lo que parece funcionar para mí era ignorar la NullPointerException
:
private void tryConnectAudio() { verifyBluetoothSupport(); try { mAudioManager.startBluetoothSco(); } catch (NullPointerException e) { // TODO This is a temp workaround for Lollipop Log.d(TAG, "startBluetoothSco() failed. no bluetooth device connected."); } }
@ Julian Claudino, Esto funciona para mí y el enrutamiento a través del micrófono Bluetooth, asegúrese de que el dispositivo Bluetooth es reconocido y conectado:
private void verifyBluetoothSupport() { getActivity().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1); Log.d(TAG, "Audio SCO state: " + state); if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) { Toast.makeText(getActivity(), "Bluetooth Connected", Toast.LENGTH_SHORT).show(); getActivity().unregisterReceiver(this); } } }, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)); }
Espero que esto ayude a alguien!
- Buscar ver cerrar icono aparecer deshabilitado en lugar de blanco
- StartVoiceRecognition con auriculares bluetooth no funciona