Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpeechRecognizer.isRecognitionAvailable() always false in Android 11

As the title implies, SpeechRecognizer.isRecognitionAvailable() returns false in Android 11 and I am not sure why that is as the device (Pixel 3 XL) is equipped to recognize speech. The documentation doesn't indicate that it changed in API v30. The strange thing is that I still get the STT prompt successfully even if isRecognitionAvailable is false. Below is sample code illustrating this point. Why is the isRecognitionAvailable check always false? The code is not complete by any means but I've added the important related sections:

AndroidManifest.xml
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
...
MainActivity.kt
...
override fun onCreate(savedInstanceState: Bundle?) {
...
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
        if(shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) { //rationale prompt
        }
        val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()
        ){ isGranted: Boolean ->
            if(isGranted) { checkSTT() }
            else { //error perms not granted
            }
        requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
    } else { checkSTT() }
}

private fun checkSTT() {
    if(SpeechRecognizer.isRecognitionAvailable(this)) { runSTT() }
    else { runSTT() //Run anyway because isRecognitionAvailable is always false and STT works anyway?
    }
}

private fun runSTT() {
    //Yes, I know this is deprecated
    val sttIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
    sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
    sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.US)
    startActivityForResult(sttIntent, 1)
}
...
like image 831
Tom Avatar asked Nov 04 '20 00:11

Tom


Video Answer


1 Answers

I figured out the solution. For some reason, as of API v30, you must add the following to the Manifest file for SpeechRecognizer.isRecognitionAvailable(Context) to return true. My testing found that it only works when placed outside of the <application> tag even though it complains that "element queries is not allowed here". Add suppress AndroidElementNotAllowed to remove the warning.

<!--suppress AndroidElementNotAllowed -->
<queries>
    <intent>
        <action android:name="android.speech.RecognitionService" />
    </intent>
</queries>
<application...
like image 74
Tom Avatar answered Sep 21 '22 12:09

Tom