【问题标题】:Why does Intent.createChooser() need a BroadcastReceiver and how to implement?为什么 Intent.createChooser() 需要一个 BroadcastReceiver 以及如何实现?
【发布时间】:2025-12-23 00:00:11
【问题描述】:

从我的onOptionsItemSelected() 实现中调用的以下 sn-p 可以很好地将用户从我的应用程序带到邮件客户端,并预先填写了电子邮件地址、主题和正文。我将此作为一种简单的方式让用户给我反馈。

String uriText =
    "mailto:" + emailAddress +
    "?subject=" + subject +
    "&body=" + body;

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uriText));
startActivity(Intent.createChooser(emailIntent, "Pick an email app:"));

当邮件应用程序打开时(在我的 Nexus S 上,Android 4.0.4),LogCat 输出以下内容,我不知道为什么; Google 和 SO 搜索 createChooser unregisterReceiver 似乎没有结果,而且我找不到很多 createChooser() 的例子,它们也以有助于这种情况的方式调用 unregisterReceiver()

04-08 21:26:19.094: E/ActivityThread(27894): Activity com.android.internal.app.ChooserActivity 泄露了最初在此处注册的 IntentReceiver com.android.internal.app.ResolverActivity$1@4150aac8。您是否错过了对 unregisterReceiver() 的调用?

04-08 21:26:19.094: E/ActivityThread(27894): android.app.IntentReceiverLeaked: Activity com.android.internal.app.ChooserActivity 已泄露 IntentReceiver com.android.internal.app.ResolverActivity$1@4150aac8最初是在这里注册的。您是否错过了对 unregisterReceiver() 的调用?

04-08 21:26:19.094:E/ActivityThread(27894):在 android.app.LoadedApk$ReceiverDispatcher.(LoadedApk.java:763)

这感觉像是一个 Android 错误,因为我自己的代码没有调用 registerReceiver(),那么为什么 Android 抱怨我需要调用 unregisterReceiver()

【问题讨论】:

  • 我的 nexus 4.0.4 也有同样的问题
  • 模拟器会出现这种情况吗?如果不是,this 可能是相关的。

标签: android android-intent broadcastreceiver


【解决方案1】:

我在装有 4.0.4 的 Galaxy Nexus 上也看到了这一点,但前提是只有一个选项并且选择器没有出现。

这是 Android 源代码中的一个错误 - 您对此无能为力。他们的 ResolverActivity 注册了一个 BroadcastReceiver,但并不总是注销它。

更多细节:

Intent.createChooser() 将启动一个 ResolverActivity。在 onCreate() 中,活动调用

mPackageMonitor.register(this, false);

mPackageMonitor 是一个 BroadcastReceiver,在 register() 内它会在活动中注册自己。通常,接收者在onStop() 中未注册。但是,稍后在onCreate() 中,代码会检查用户可以选择多少选项。如果只有一个,它会调用finish()。由于在onCreate() 中调用了finish(),因此从不调用其他生命周期方法,它直接跳转到onDestroy() - 泄漏接收器。

我在 Android 问题数据库中没有看到这方面的错误,所以我created one

有关更多信息,您可以在代码中看到:

附带说明一下,Google 以电子邮件为例说明您何时不想使用选择器,因此您可以考虑正常启动 Intent。请参阅 Intent#ACTION_CHOOSER 的 javadocs。

【讨论】:

  • 你有没有链接参考谷歌说不要使用选择电子邮件?
  • 它在 Intent#ACTION_CHOOSER 的 javadocs 中。您可以使用上面的链接或在 Eclipse 中查看它们。
  • 仅供参考,无论有多少选项,这似乎都发生在 Android 4.4 上。例如,将意图类型更改为“text/html”会有所帮助,但它也限制了实际可以共享的应用程序的数量。知道为什么 Android 4.4 会导致这种情况吗?
  • Android 4.4 似乎存在严重问题,因为该问题出现在 Youtube、Tumblr 和其他各种应用程序上。这是我的解决方案:*.com/questions/19827280/…
【解决方案2】:

简单解决问题。

更多信息在这里:https://developer.android.com/training/basics/intents/sending.html

Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

PackageManager pkManager = getPackageManager();
List<ResolveInfo> activities = pkManager.queryIntentActivities(mapIntent, 0);

if (activities.size() > 1) {
    // Create and start the chooser
    Intent chooser = Intent.createChooser(mapIntent, "Open with");
    startActivity(chooser);

  } else {
    startActivity( mapIntent );
}

【讨论】:

    最近更新 更多