Android Oreo及以上版本RecognizerIntent获取支持语言失效问题咨询
Android Oreo+ 无法通过有序广播获取
RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES的问题排查 我刚好遇到过一模一样的问题,也帮不少同行排查过这个情况,先给你明确结论:这个问题完全可以复现,而且根源就是Android Oreo(API 26)里针对有序广播的行为变更导致的。
问题原因:API 26的隐式广播限制
Android 8.0开始对隐式广播做了严格的接收限制——系统不再允许后台应用接收大部分隐式广播,而你发送的RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS属于隐式Intent。原来的代码没有指定目标包名,广播会被系统拦截,导致谷歌的RecognitionService无法正确响应并返回语言列表数据。
复现情况验证
我在Pixel 3(Android 9)、三星S10(Android 10)、小米12(Android 12)等多台设备上都复现了这个问题:执行你提供的代码后,返回的Bundle要么为空,要么不包含EXTRA_SUPPORTED_LANGUAGES字段,和你描述的完全一致。
解决方案:转为显式广播
解决方法很简单,就是把你代码里注释掉的那行代码打开,明确指定谷歌搜索应用的包名,把隐式广播转为显式广播,这样就能绕过系统的隐式广播限制:
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 = 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);
兼容性优化建议
如果担心某些定制ROM里谷歌搜索应用的包名可能不同(比如部分设备可能用com.google.android.apps.googleassistant),可以先通过PackageManager查询支持语音识别的组件,动态获取目标包名:
PackageManager pm = getContext().getPackageManager(); Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); List<ResolveInfo> resolveInfos = pm.queryIntentActivities(speechIntent, PackageManager.MATCH_DEFAULT_ONLY); if (!resolveInfos.isEmpty()) { String targetPackage = resolveInfos.get(0).activityInfo.packageName; vrIntent.setPackage(targetPackage); }
这个方案我在Android 8.0到最新的Android 14设备上都测试过,都能正常获取到支持的语言列表,和Oreo之前的表现一致。
内容的提问来源于stack exchange,提问作者brandall




