AudioManager.startBluetoothSco()在Android Lollipop上崩溃

时间:2014-10-29 23:07:31

标签: android bluetooth android-5.0-lollipop

在清单中针对API级别18或更高级别调用AudioManager.startBluetoothSCO()时,文档指出已建立原始音频连接,并且如果使用针对API 17或更低版​​本的虚拟语音呼叫。

直到API级别20(Android L预览版),此功能正常,针对任何API。但是,当使用最新的Android Lollipop构建LPX13D并且目标API级别为18或更高时,我会遇到以下堆栈跟踪崩溃:

E / AndroidRuntime(31705):引起:java.lang.NullPointerException:尝试在空对象引用上调用虚方法'java.lang.String android.bluetooth.BluetoothDevice.getAddress()' E / AndroidRuntime(31705):在android.os.Parcel.readException(Parcel.java:1546) E / AndroidRuntime(31705):在android.os.Parcel.readException(Parcel.java:1493) E / AndroidRuntime(31705):在android.media.IAudioService $ Stub $ Proxy.startBluetoothSco(IAudioService.java:1587) E / AndroidRuntime(31705):在android.media.AudioManager.startBluetoothSco(AudioManager.java:1468)

如果我在Android Lollipop上定位API级别17或更低级别,一切都按预期工作。

我认为问题的根源在于改变Android的音频代码,该代码发生在文件AudioService.java第2392行的API级别21中:

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

看起来SCO_MODE_UNDEFINED应该是SCO_MODE_RAW。如果查看该文件,您可以看到在几个地方检查了SCO_MODE_RAW,但实际上从未在任何地方传递过。

是否有其他人遇到此次崩溃?有没有人知道比将目标SDK降级到17更好的解决方案?如果没有,你能不能为我提交给谷歌的bug report加注星标,以增加它的可能性: - )

3 个答案:

答案 0 :(得分:4)

正如@xsveda所写,如果没有连接耳机,你将在Lollipop上收到NPE。

您可以先尝试检查蓝牙耳机连接:

mAudioManager.isWiredHeadsetOn()

正如所描述的文档isWiredHeadsetOn()doc link)已被删除,仅用于检查耳机是否已连接。

在此之后,您可以使用startBluetoothSco()连接。至于我,我使用了这段代码:

这一个开始:

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

这个停止:

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

希望它有所帮助。

答案 1 :(得分:0)

经过几天的绝望之后,我找到了一个简单的解决方法:

只有在没有连接蓝牙设备的情况下,

startBluetoothSco()才会抛出NPE,因此可以捕获并忽略它,因为没有人可以与#34;交谈。如果连接了BT耳机,则SCO成功启动并且播放正在运行!

答案 2 :(得分:0)

现在看来对我有用的是忽略了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,这适用于我并通过蓝牙麦克风进行路由,确保识别并连接蓝牙设备:

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

希望这有助于某人!