来电后蓝牙SCO失败

时间:2014-06-08 08:17:14

标签: android bluetooth bluetooth-sco

我正在尝试通过SCO发送应用程序的所有音频。

我能够成功发送音频,

但是当有来电时,我需要断开SCO表格,以便应用音频不会干扰通话,

问题在于,当我尝试在通话后将音频重新路由到SCO时,它不起作用。

以下是我用来将音频发送到SCO的代码:

public class BluetoothManager {
// For Bluetooth connectvity
private static String TAG = "BluetoothManager";
private static BluetoothAdapter mBluetoothAdapter =    BluetoothAdapter.getDefaultAdapter();
private static AudioManager aM;

/**
 * Set the audio manager of the device.
 * @param c: The context this method is called from
 */
public static void setAudioManager(Context c) {
    aM = (android.media.AudioManager)c.getSystemService(Context.AUDIO_SERVICE);
}

/**
 * Check if a Bluetooth headset is connected. If so, route audio to Bluetooth SCO.
 */
private static void initializeAudioMode(Context context) {
    BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.HEADSET) {
                BluetoothHeadset bh = (BluetoothHeadset) proxy;
                List<BluetoothDevice> devices = bh.getConnectedDevices();
                if (devices.size() > 0) {
                    enableBluetoothSCO();
                }
            }
            mBluetoothAdapter.closeProfileProxy(profile, proxy);
        }
        public void onServiceDisconnected(int profile) {}
    };
    mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
}

/**
 * Bluetooth Connectvity
 *   The following methods are associated with enabling/disabling Bluetooth.
 *   In the future we may want to disable other sources of audio.
 */
private static void enableBluetoothSCO() {
    aM.setMode(AudioManager.MODE_IN_CALL);
    aM.startBluetoothSco();
    aM.setBluetoothScoOn(true);
}

/** Right now, this simply enables Bluetooth */
@SuppressLint("NewApi")
public static boolean enableBluetooth(Context c) {
    // If there is an adapter, enable it if not already enabled
    if (mBluetoothAdapter != null) {

        if (!mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.enable(); 
        }

        setAudioManager(c);
        initializeAudioMode(c);
        Log.e(TAG, "SCO: " + aM.isBluetoothScoOn());
        Log.e(TAG, "A2DP: " + aM.isSpeakerphoneOn());
        return true;
    } else {
        Log.v(TAG, "There is no bluetooth adapter");
        return false;
    }
}

/** Right now, this simply disables Bluetooth */
public static void disableBluetooth() {
    // If there is an adapter, disabled it if not already disabled
    if (mBluetoothAdapter != null) {
        if (mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.disable(); 
        }
    } else {
        Log.v(TAG, "There is no bluetooth adapter");
    }
}

public static void restartBluetooth(){
    aM.setMode(AudioManager.MODE_IN_CALL);

}
public static void stopBluetooth(){
    aM.setMode(AudioManager.MODE_NORMAL);

}

}

当我正确拨打stopBluetooth()时,应用程序的音频不再发送到耳机,

但是,当我拨打restartBluetooth()时,播放的音频并非按预期播放,而是来自手机扬声器。

5 个答案:

答案 0 :(得分:1)

呼叫结束后SCO链路是否可能被关闭?如果是这种情况,那么SCO链接也必须与路由音频一起启动。

您是否尝试在restartBluetooth()

中调用enableBluetoothSCO()

答案 1 :(得分:1)

您可能需要致电:

aM.startBluetoothSco(); aM.setBluetoothScoOn(true);

设置模式后。

答案 2 :(得分:1)

在你的重启函数里面再次初始化所有东西,看它是否有效。像这样:

public static void restartBluetooth(){
    enableBluetooth(getApplicationContext());
}

如果这样做,则意味着当呼叫结束时,由于某种原因,最后一次初始化将丢失。

答案 3 :(得分:1)

对于仍然对此有疑问的任何人,都需要做一些事情。您需要做的第一件事是跟踪电话状态。您可以在此处查看如何执行此操作: How to know Phone call has ended?

状态闲置时,表示来电已结束。现在,如果您此时尝试重新连接蓝牙,您会发现它仍然不起作用,因为调用“释放”蓝牙设备需要花费一段时间(大约2秒钟)。 因此,您有两个选择,请稍等片刻,然后尝试重新连接,或者可以将另一个侦听器添加到BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED。

然后,您可以添加全局布尔值 isIdle ,该值在TelephonyManager.CALL_STATE_IDLE时为true,在TelephonyManager.CALL_STATE_OFFHOOK时为false(否则,将在传入呼叫期间重新连接至蓝牙)。此时,当BluetoothHeadset.STATE_DISCONNECTED和 isIdle 为true时,然后重新连接到蓝牙。

Assigner = User.alias()
assignments = (
    UserAssignment
        .select(
            Assigner,
            User,
            UserAssignment,
            Worker
        )
        .join(User, on=UserAssignment.user_id == User.id)
        .switch(UserAssignment)
        .join(Assigner, on=UserAssignment.assigner_id == Assigner.id)
        .switch(UserAssignment)
        .join(Worker)
        .switch(UserAssignment)
        .where(
            UserAssignment.user_id == user_id,
            UserAssignment.active == True,
        )
)

答案 4 :(得分:0)

Google Doc say's that

“电话应用程序始终优先使用电话的SCO连接。如果在电话通话时调用此方法,它将被忽略。同样,如果在应用程序使用时收到或发送呼叫在SCO连接中,应用程序的连接将丢失,并且在呼叫结束时不会自动返回。“

因此,当呼叫断开时,您必须通过调用 startBluetoothSco()

重新建立连接