【问题标题】:RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS in Oreo奥利奥中的 RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS
【发布时间】:2018-09-28 02:49:25
【问题描述】:

在大多数 Android 设备中,RecognitionService 将由 Google 的原生“Now/Assistant”应用程序提供。

在 Android Oreo 之前,我可以使用以下简单代码查询 Google 识别器支持的语言:

final Intent vrIntent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);

// vrIntent.setPackage("com.google.android.googlequicksearchbox");

getContext().sendOrderedBroadcast(vrIntent, null, new BroadcastReceiver() {

    @Override
    public void onReceive(final Context context, final Intent intent) {

                // final Bundle bundle = intent.getExtras();
                final Bundle bundle = getResultExtras(true);

                if (bundle != null) {

                    if (bundle.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES)) {
                        Log.i("TAG", "onReceive: EXTRA_SUPPORTED_LANGUAGES present");

                        final ArrayList<String> vrStringLocales = bundle.getStringArrayList(
                                RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);

                        Log.i("TAG", "onReceive: EXTRA_SUPPORTED_LANGUAGES size: " + vrStringLocales.size());

                    } else {
                        Log.w("TAG", "onReceive: missing EXTRA_SUPPORTED_LANGUAGES");
                    }

                } else {
                    Log.w("TAG", "onReceive: Bundle null");
                }

}, null, 1234, null, null);

但是,从 8.0+ 开始,额外的 RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES 不再包含在响应中。

在我尝试将此作为错误提交之前,我想先看看其他人是否可以复制 - 但还要检查是否有一个有序广播 behavioural change in API 26 我不知何故忽略了,这可能是造成这种情况的原因。

提前致谢。

【问题讨论】:

  • 您是否尝试过使用getVoiceDetailsIntent()
  • @azizbekian 谢谢。我有 - 它只是返回 RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS 的显示意图
  • 能否通过检查getResultCode() == Activity.RESULT_OKgetResultData()receive()函数开头是否包含任何值来做简单的调试和验证Broadcast是否成功完成?
  • @R.Zagórski 结果代码与请求代码匹配,在上面的示例中为 1234。结果数据为空,但文档确实声明“这通常为空”。此行为与 pre-Oreo 相同,后者确实包含所需的额外语言。
  • 我已经用 API 26 在 Android Emulator 上测试了你的代码,我到达了这个Log.i("TAG", "onReceive: EXTRA_SUPPORTED_LANGUAGES present");compileSdkVersion 27 buildToolsVersion "27.0.3" defaultConfig { applicationId "it.versionestabile.stackover001" minSdkVersion 19 targetSdkVersion 27 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" }你是说没有达到那个代码吗?

标签: java android speech-recognition voice-recognition google-voice-search


【解决方案1】:

所以,我无法复制,但如果您不设置包名称,请进一步复制到 cmets

vrIntent.setPackage("com.google.android.googlequicksearchbox");

然后它失败了,否则一切对我来说都很好。

这是我用来测试它的基本活动。

package it.versionestabile.stackover001;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.speech.RecognizerIntent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;

import static java.security.AccessController.getContext;

/**
 * https://*.com/questions/48500077/recognizerintent-action-get-language-details-in-oreo
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Intent vrIntent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
        vrIntent.setPackage("com.google.android.googlequicksearchbox");

        PackageManager packageManager = getPackageManager();

        for (PackageInfo packageInfo: packageManager.getInstalledPackages(0)) {
            if (packageInfo.packageName.contains("com.google.android.googlequicksearchbox"))
                Log.d("AAA", packageInfo.packageName + ", "  + packageInfo.versionName);
        }

        this.sendOrderedBroadcast(vrIntent, null, new BroadcastReceiver() {

            @Override
            public void onReceive(final Context context, final Intent intent) {

                // final Bundle bundle = intent.getExtras();
                final Bundle bundle = getResultExtras(true);

                if (bundle != null) {

                    if (bundle.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES)) {
                        Log.i("TAG", "onReceive: EXTRA_SUPPORTED_LANGUAGES present");

                        final ArrayList<String> vrStringLocales = bundle.getStringArrayList(
                                RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);

                        Log.i("TAG", "onReceive: EXTRA_SUPPORTED_LANGUAGES size: " + vrStringLocales.size());

                    } else {
                        Log.w("TAG", "onReceive: missing EXTRA_SUPPORTED_LANGUAGES");
                    }

                } else {
                    Log.w("TAG", "onReceive: Bundle null");
                }
            }

            }, null, 1234, null, null);
    }
}

我已经在 Android Studio 2.3 和 3.0.1 以及具有 API 26 和 27 的模拟器上对其进行了测试。

上面的代码一切正常。

但是如果你注释掉这一行:

vrIntent.setPackage("com.google.android.googlequicksearchbox");

在奥利奥上它不起作用。

我仍然建议使用 Package Manager 以如下方式检查 Google Now 的存在:

PackageManager packageManager = getPackageManager();

for (PackageInfo packageInfo: packageManager.getInstalledPackages(0)) {
    if (packageInfo.packageName.contains("com.google.android.googlequicksearchbox"))
        Log.d("AAA", packageInfo.packageName + ", "  + packageInfo.versionName);
// TODO - set a boolean value to discriminate the precence of google now
}

为了确定您是否拥有正确版本的 Google Now。

希望对你有帮助!

【讨论】:

  • 我将发布另一个问题来尝试找出为什么在 Oreo 中您需要指定包名称...再次感谢您!
  • 对比一下,在 OREO 之前应该是什么样子?谢谢
  • @RonTLV 在 Oreo 之前它也可以在没有明确将包设置为意图的情况下工作。
  • 最佳解决方案,我在 Android 9 中测试过,它可以工作。我只在我的 Intent 中添加了“setPackage("com.google.android.googlequicksearchbox")”这一行并且它起作用了。谢谢