Сбой 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() Звук воспроизводится НЕ из наушников, как положено, а через динамики телефона.

4 ответа

Вам, вероятно, нужно позвонить:

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

после того, как вы установили режим.

Google Doc говорит, что это

"Приложение телефона всегда имеет приоритет при использовании соединения SCO для телефонии. Если этот метод вызывается во время разговора по телефону, он будет игнорироваться. Аналогично, если вызов принят или отправлен, когда приложение использует соединение SCO соединение будет потеряно для приложения и НЕ вернется автоматически после завершения вызова."

Поэтому, когда вызов отключен, вам необходимо восстановить соединение, вызвав startBluetoothSco()

Внутри вашей функции перезапуска снова все инициализируйте и посмотрите, работает ли она. вот так:

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

если это работает, то это означает, что когда вызов завершается, последняя инициализация по какой-то причине теряется.

Для тех, у кого все еще есть проблемы с этим, необходимо сделать несколько вещей. Первое, что вам нужно сделать, это отслеживать состояние телефона. Вы можете увидеть, как это сделать, здесь: Как узнать, что телефонный звонок закончился?

Когда состояние неактивно, это означает, что входящий вызов завершен. Теперь, если вы попытаетесь повторно подключить bluetooth в этот момент, вы обнаружите, что он все еще не работает, так как требуется некоторое время (примерно 2 секунды) для вызова, чтобы "освободить" устройство bluetooth. Таким образом, у вас есть два варианта: немного подождите, а затем попробуйте повторно подключиться, или вы можете добавить другого слушателя в BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED.

Затем вы можете добавить глобальное логическое значение isIdle, которое имеет значение true, если TelephonyManager.CALL_STATE_IDLE, или false, когда TelephonyManager.CALL_STATE_OFFHOOK (в противном случае вы повторно подключитесь к BlueTooth во время входящего вызова). На этом этапе, когда BluetoothHeadset.STATE_DISCONNECTED и isIdle имеет значение true, затем повторно подключитесь к Bluetooth.

@Override public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals((BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED))){
        int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
        switch(state) {
            case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
                if (isIdle){
                    //reconnect bluetooth 
                }
                break;
        }
    }
    if(("OFFHOOK").equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
        isIdle = false;
        // turn bluetooth off
    }
    if(("IDLE").equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
        isIdle = true;
    }
}

Возможно ли, что связь SCO была прервана после завершения вызова? Если это так, то необходимо также установить связь SCO с маршрутизацией аудио.

Вы пытались вызвать enableBluetoothSCO() в restartBluetooth()

Другие вопросы по тегам