【问题标题】:How to query for the default SpeechRecognizer如何查询默认的 SpeechRecognizer
【发布时间】:2024-01-11 06:12:01
【问题描述】:

如何找出默认系统语音识别器的ComponentName,即调用createSpeechRecognizer(Context context)时返回的那个? (其实我只需要找出它支持哪些输入语言,所以如果只有那个答案,那我也很感激。)

框架解决了这个问题

String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
                        Settings.Secure.VOICE_RECOGNITION_SERVICE);

(见source code of SpeechRecognizer。)

但是,该解决方案似乎不适用于第三方应用。

【问题讨论】:

    标签: java android speech-recognition


    【解决方案1】:

    但是,第三方应用似乎无法使用此解决方案。

    我假设您得出这样的结论是因为Settings.Secure.VOICE_RECOGNITION_SERVICE 不是公共 API。但是,Settings.Secure.getString() 需要在安全表中查找第二个参数的行名。因此,您只需提供您要查找的行的实际名称:"voice_recognition_service"

    也就是说,您可以使用与SpeechRecognizer 相同的代码,只需稍作改动:

    String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
            "voice_recognition_service");
    

    希望这会有所帮助。

    【讨论】:

    • 谢谢!这是我目前正在使用的,但我想可能还有另一种(首选)方式。
    【解决方案2】:

    更新(我误读了原来的问题)

    SpeechRecognizer 不是进行语音处理的东西,但是您传递给 SpeechRecognizer 的 Intent 是(通过startListening(Intent intent))。该意图使用RecognizerIntent.ACTION_RECOGNIZE_SPEECH,并且可以以老式方式检测到AFAIK。

    要检测默认值,请尝试解析您希望为其找到默认值但设置了PackageManager.MATCH_DEFAULT_ONLY 的 Intent。

    未经测试的代码:

    String detectDefaultSpeechRecognizer(Context context) {
      final Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
      // 1: Try to find the default speech intent
      final ResolveInfo defaultResolution = context.getPackageManager().resolveService(speechIntent, PackageManager.MATCH_DEFAULT_ONLY);
      if (defaultResolution != null) {
        final ActivityInfo activity = defaultResolution.activityInfo;
        if (!activity.name.equals("com.android.internal.app.ResolverActivity")) {
          //ResolverActivity was launched so there is no default speech recognizer
          return "";
        }
      }
      // 2: Try to find anything that we can launch speech recognition with. Pick up the first one that can.
      final List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentServices(speechIntent, PackageManager.MATCH_DEFAULT_ONLY);
      if (!resolveInfoList.isEmpty()) {
        speechIntent.setClassName(resolveInfoList.get(0).activityInfo.packageName, resolveInfoList.get(0).activityInfo.name);
        return resolveInfoList.get(0).activityInfo.packageName;
      }
      return "";
    }
    

    老答案

    查看 GAST,它可以检查语音识别器是否支持某种语言。
    https://github.com/gast-lib/gast-lib/blob/master/library/src/root/gast/speech/SpeechRecognizingActivity.java#L70

    您也可以尝试手动检查&lt;recognition-service&gt; 元数据标签。 http://developer.android.com/reference/android/speech/RecognitionService.html#SERVICE_META_DATA

    【讨论】:

    • 谢谢,但我不明白这如何回答我的问题。一旦我知道要查询哪个识别器,我已经知道如何检查识别器支持哪些语言。我需要找出哪个识别器已设置为默认值。元数据在这里没有帮助,因为这不允许识别器声明它是默认值,只能声明它是识别器。
    • 我明白了。我更新了我的答案以匹配更多你的意思。 SpeechRecognizer 并不是真正做语音识别,它只是启动服务。
    • 你的新答案不是查询活动吗?我只对服务感兴趣。
    • 该死!你是对的!我的错。好在还有resolveService(),它的工作原理与resolveActivity() 一样。我更新了代码示例。
    • 没问题!如果有帮助,请告诉我。
    【解决方案3】:

    如果您只想了解默认系统语音识别器支持哪些输入语言 (createSpeechRecognizer (Context context)),有一种更直接的方法。

    您需要做的就是使用RecognizerIntent.getVoiceDetailsIntent Intent 来检查默认的系统语音识别器语言:

    Intent intent = RecognizerIntent.getVoiceDetailsIntent(getApplicationContext());
    
            if (intent != null) {
                ctx.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, final Intent intent) {
                        Log.d(TAG,
                                "Receiving Supported Speech Recognition Languages broadcast "
                                        + intent);
    
                        final Bundle extra = getResultExtras(false);
    
                        if ((getResultCode() == Activity.RESULT_OK)
                                && (extra != null)
                                && (mHandler != null)
                                && ((extra
                                        .containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES)) || (extra
                                        .containsKey(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE)))) {
    
                            List<String> supportedLanguages = extra
                                    .getStringArrayList(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
                            String prefLang = extra
                                    .getString(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE);
    
                        }
                    }
    
                },
    
                null, Activity.RESULT_OK, null, null);
            }
    

    【讨论】:

    • @Kaarel 这不是您要找的吗?找出默认系统语音识别器支持的语言的简单方法?请注意,所有代码都在公共 API 中(这是可取的)并且更易于维护
    • 谢谢。我认为getVoiceDetailsIntent 给了我实现ACTION_WEB_SEARCHactivity(参见源代码)。我需要一项服务。