为什么Intent.createChooser()需要一个BroadcastReceiver以及如何实现?

时间:2012-04-09 04:39:03

标签: android android-intent broadcastreceiver

从我的onOptionsItemSelected()实现调用的以下代码段可以很好地将用户从我的应用程序带到邮件客户端,邮件地址,主题和正文已预先填好。我正在使用它作为让用户给我反馈的简单方法。

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:"));

当邮件应用程序打开时(在我的带有Android 4.0.4的Nexus S上),LogCat输出以下内容,我无法弄清楚原因; Google和SO搜索 createChooser unregisterReceiver 似乎毫无结果,我找不到很多createChooser()的例子,这些例子也会以帮助这种情况的方式调用unregisterReceiver()

  

04-08 21:26:19.094:E / ActivityThread(27894):活动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()

2 个答案:

答案 0 :(得分:11)

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

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

更多细节:

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

mPackageMonitor.register(this, false);

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

我没有在Android问题数据库中看到此错误,因此我created one

有关详细信息,您可以在代码中看到:

作为旁注,Google使用电子邮件作为您不想使用选择器的示例,因此您可以考虑正常启动意图。请参阅Intent#ACTION_CHOOSER的javadoc。

答案 1 :(得分:4)

简单解决问题。

此处有更多信息: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 );
}