oreo中的sendOrderedBroadcast setPackage要求

除非我专门设置包名,否则为什么Android Oreo中的以下有序广播会失败?

final Intent vrIntent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS); // Setting the package it will work. Omitting, it will fail // 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 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); 

如果未设置包名,则将丢失EXTRA_SUPPORTED_LANGUAGES

我最近问了一个赏金问题 ,我的’遗留代码’没有设置包名,在Oreo中失败了,但在以前的Android版本上成功运行。

检查了API 26中的所有行为变化后,我看不到任何可以解释这一点的内容。

有人可以解释可能的原因吗?

注意:示例代码和问题假设设备已安装Google的“Now”应用程序以提供RecognitionService

好的,我重现了这个问题。 1234结果代码是一个红色的鲱鱼 – 看起来像RecognizerIntent背后的过程没有设置结果代码,所以你得到初始代码。

但是,您确实在Android 8.1(并且,可能是8.0)上收到此错误消息:

 W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.speech.action.GET_LANGUAGE_DETAILS flg=0x10 } to com.google.android.googlequicksearchbox/com.google.android.voicesearch.intentapi.IntentApiReceiver 

这就是“你在清单中注册了一个接收器,我们不打算给你播放,因为你在后台”错误。

这个经过轻度测试的sendImplicitOrderedBroadcast()方法解决了这个问题,同时原则上维护了接收器的顺序(按优先级降序):

  private void sendImplicitOrderedBroadcast(Intent i, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { PackageManager pm=getPackageManager(); List matches=pm.queryBroadcastReceivers(i, 0); Collections.sort(matches, (left, right) -> right.filter.getPriority()-left.filter.getPriority()); for (ResolveInfo resolveInfo : matches) { Intent explicit=new Intent(i); ComponentName cn= new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName, resolveInfo.activityInfo.name); explicit.setComponent(cn); sendOrderedBroadcast(explicit, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras); } } 

我冒昧地提出了一个问题 。