Android speech recognition through a Bluetooth headset sometimes skips a beep to make the user speak

My application already recognizes speech. A user told me that he is not working with a Bluetooth headset. I was able mainly to get speech recognition while working on a Bluetooth headset (thanks to another Stack Overflow contributor, not thanks to the official Android documentation).

However, there is one unpleasant problem: when you switch to using a Bluetooth headset, it may briefly erase the audio output during the switch. In particular, it can sometimes omit the audio signal, which usually asks the user for speech recognition.

My current workaround is to set the delay to one second after the Bluetooth headset has been connected to the SCO audio channel before performing voice recognition.

My question is: is there a more reliable way to avoid this conflict?

static AudioManager sAudioManager;
static BluetoothHeadset sBluetoothHeadset;
static BluetoothDevice sBluetoothDevice;

static public void initBluetooth(Context pContext)
{
    sAudioManager = (AudioManager) pContext.getSystemService(Context.AUDIO_SERVICE);

    // Register to get notifications about Bluetooth profiles

    sBluetoothAdapter.getProfileProxy(
        pContext, new BluetoothProfileListener(), BluetoothProfile.HEADSET);

    // Register to receive notification when the headset is dis/connected

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
    pContext.registerReceiver(
        new BluetoothHeadsetBroadcastReceiver(), intentFilter);
}

public static void startSpeechRecognition()
{
    sAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
    sAudioManager.startBluetoothSco();
    sAudioManager.setBluetoothScoOn(true);

    sBluetoothHeadset.startVoiceRecognition(sBluetoothDevice);
}

public static void stopSpeechRecognition()
{
    sBluetoothHeadset.stopVoiceRecognition(sBluetoothDevice);

    sAudioManager.stopBluetoothSco();
    sAudioManager.setBluetoothScoOn(false);
    sAudioManager.setMode(AudioManager.MODE_NORMAL);
}

static public void doSpeechRecognition(Context pContext)
{
    SpeechRecognizer sr = SpeechRecognizer.createSpeechRecognizer(pContext);
    Intent intent =
        new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(
        RecognizerIntent.EXTRA_LANGUAGE_MODEL,
        RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    sr.startListening(intent);
}

static public class BluetoothHeadsetBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context pContext, Intent pIntent)
    {
        int state = pIntent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
        if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED)
        {
            // CURRENT WORKAROUND
            // Delay speech recognition to avoid obliterating beep prompt

            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
            };

            doSpeechRecognition(pContext);
        }
    }
}

static public class BluetoothProfileListener implements BluetoothProfile.ServiceListener
{
    @Override
    public void onServiceConnected(int pProfile, BluetoothProfile pProxy)
    {
        sBluetoothHeadset = (BluetoothHeadset) pProxy;

        List<BluetoothDevice> devices = pProxy.getConnectedDevices();
        int numDevices = devices.size();

        if (numDevices > 0)
        {
            BluetoothDevice device = devices.get(0);
            sBluetoothDevice = device;
        }
    }
}
+4
source share

Source: https://habr.com/ru/post/1657772/


All Articles