2014-10-29 26 views
11

Beim Aufruf von AudioManager.startBluetoothSCO() während der Ausrichtung auf API-Stufe 18 oder höher im Manifest wird in der Dokumentation festgelegt, dass eine reine Audioverbindung hergestellt wird und API 17 oder darunter eine virtuelle Stimme verwendet wird Anruf wird verwendet.AudioManager.startBluetoothSco() stürzt auf Android Lollipop ab

Bis API-Level 20 (Android L Preview) funktionierte dies gut und zielte auf jede API ab. Bei der Verwendung des neuesten Android Lollipop Build LPX13D und der Targeting-API der Stufe 18 oder höher stürzt ich jedoch mit folgendem Stack-Trace ab:

E/AndroidRuntime (31705): Verursacht von: java.lang.NullPointerException: Versuch zum Aufruf virtuelle Methode 'java.lang.String android.bluetooth.BluetoothDevice.getAddress()' auf einem Nullobjekt Referenz E/AndroidRuntime (31705): bei android.os.Parcel.readException (Parcel.java:1546) E/AndroidRuntime (31705): at android.os.Parcel.readException (Parcel.java:1493) E/AndroidRuntime (31705): bei android.media.AudioService $ Stub $ Proxy.startBluetoothSco (IAudioService.java:1587) E/AndroidRuntime (31705): bei android.media.AudioManager.startBluetoothSco (AudioManager.java:1468)

Wenn ich API-Ebene 17 oder niedriger auf Android Lollipop anwende, funktioniert alles wie erwartet.

Ich glaube, die Ursache des Problems in einer Änderung Audiocode zu Androids liegt, die in API-Ebene 21 in der Datei AudioService.java Linie geschah 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); 
} 

Es ist wie SCO_MODE_UNDEFINED sieht stattdessen SCO_MODE_RAW sein sollte. Wenn Sie durch die Datei schauen, können Sie sehen, dass SCO_MODE_RAW an einigen Stellen überprüft wird, aber nirgends tatsächlich übergeben wird.

Hat noch jemand diesen Absturz erlebt? Kennt jemand eine bessere Lösung, als das Ziel-SDK auf 17 herabzustufen? Wenn nicht, könnten Sie bitte Sterne die bug report ich mit Google reichte die Chance zu erhöhen, dass es

+0

Auch wenn ich den Absturz nicht erhalte, scheint das Gerät Audio vom Bluetooth-Mikrofon nicht zu routen. –

+0

Ich habe das gleiche Problem, Mikrofon ist nicht Routing, keine Lösung dafür? –

Antwort

0

Nach einigen Tagen der Verzweiflung an :-) betrachtet werden werde ich eine einfache Abhilfe gefunden habe:

startBluetoothSco() wirft NPE Nur wenn kein Bluetooth-Gerät angeschlossen ist, kann es abgefangen und ignoriert werden, da es "niemanden gibt, mit dem man sprechen kann". Wenn beispielsweise ein BT-Headset angeschlossen ist, wird SCO erfolgreich gestartet und die Wiedergabe funktioniert!

+0

Das scheint eine bessere Problemumgehung zu sein, als das Ziel-SDK auf 17 zu setzen, aber bei weiteren Untersuchungen bemerkte ich, dass bei beiden Workarounds Audio nicht über das Bluetooth-Mikrofon geleitet wird, sondern über das Mikrofon des Telefons. Es ist leicht, dies zu verpassen, wenn Sie Ihr Telefon und Bluetooth-Gerät in der Nähe haben. –

0

Denn jetzt, was für mich zu arbeiten scheint, ignoriere den 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, Dies funktioniert für mich und Routing über das Bluetooth-Mikrofon, stellen Sie sicher, dass das Bluetooth-Gerät erkannt und verbunden:

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)); 
} 

Hoffe, das hilft jemandem!

4

Wie @xsveda schrieb, wenn kein Headset angeschlossen ist, erhalten Sie NPE auf Lollipop.

können Sie versuchen, Bluetooth-Headset-Verbindung zu überprüfen zuerst:

mAudioManager.isWiredHeadsetOn() 

Wie doc isWiredHeadsetOn() beschrieben (doc link) depricated und verwendet nur ein Headset zu überprüfen ist, verbunden ist oder nicht.

Und danach können Sie startBluetoothSco() Verbindung verwenden. Was mich betrifft habe ich diesen Code:

Dieses ist für Start:

if(mAudioManager.isWiredHeadsetOn()) 
    mAudioManager.startBluetoothSco(); 

Dieses ist für Halt:

if(mAudioManager.isBluetoothScoOn()) 
      mAudioManager.stopBluetoothSco(); 

Hoffe, es hilft.

Verwandte Themen