SpeechRecognizer.isRecognitionAvailable在Android 11中始终为false

问题描述

顾名思义,SpeechRecognizer.isRecognitionAvailable()在Android 11中返回false,我不确定为什么会这样,因为设备(Pixel 3 XL)可以识别语音documentation并不表示它在API v30中已更改。奇怪的是,即使isRecognitionAvailable为假,我仍然可以成功获得STT提示。下面是说明这一点的示例代码。为什么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)
}
...

解决方法

我想出了解决方案。由于某些原因,从API v30开始,必须将以下内容添加到清单文件中,SpeechRecognizer.isRecognitionAvailable(Context)才能返回true。我的测试发现,即使它抱怨“此处不允许元素查询”,它也只能在置于<application>标记之外时起作用。添加suppress AndroidElementNotAllowed删除警告。

<!--suppress AndroidElementNotAllowed -->
<queries>
    <intent>
        <action android:name="android.speech.RecognitionService" />
    </intent>
</queries>
<application...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...