SpeechRecognizer.isRecognitionAvailable() всегда ложно в Android 11

Как следует из названия, SpeechRecognizer.isRecognitionAvailable() возвращает false в Android 11, и я не уверен, почему это так, поскольку устройство (Pixel 3 XL) оборудовано для распознавания речи. В документации не указано, что это изменилось в API v30. Странно то, что я все еще успешно получаю приглашение STT, даже если isRecognitionAvailable ложно. Ниже приведен пример кода, иллюстрирующий этот момент. Почему проверка isRecognitionAvailable всегда ложна? Код никоим образом не завершен, но я добавил важные связанные разделы:

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

person Tom    schedule 04.11.2020    source источник


Ответы (1)


Я понял решение. По какой-то причине, начиная с API v30, вы должны добавить следующее в файл манифеста, чтобы SpeechRecognizer.isRecognitionAvailable(Context) возвращал значение true. Мое тестирование показало, что он работает только при размещении за пределами тега <application>, хотя он жалуется, что здесь не разрешены запросы к элементам. Добавьте suppress AndroidElementNotAllowed, чтобы убрать предупреждение.

<!--suppress AndroidElementNotAllowed -->
<queries>
    <intent>
        <action android:name="android.speech.RecognitionService" />
    </intent>
</queries>
<application...
person Tom    schedule 08.11.2020
comment
Еще один способ решить проблему AndroidElementNotAllowed — обновить версию Gradle вашего проекта до последней версии. - person programmer dreamer; 02.02.2021