10

我试图让我的用户从他们有电子邮件地址的联系人中选择一个联系人。这是他们单击相应按钮时执行的代码:

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);

这在我自己的手机上运行良好,但在发布我的应用程序后,我发现我的一些用户出现以下异常:

0       android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.PICK dat=content://com.android.contacts/data/emails }
1   at  android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1638)
2   at  android.app.Instrumentation.execStartActivity(Instrumentation.java:1510)
3   at  android.app.Activity.startActivityForResult(Activity.java:3244)
4   at  com.fitrocket.android.InviteMethodSelectionAct.onClick(InviteMethodSelectionAct.java:59)
5   at  android.view.View.performClick(View.java:3549)
6   at  android.view.View$PerformClick.run(View.java:14400)
7   at  android.os.Handler.handleCallback(Handler.java:605)
8   at  android.os.Handler.dispatchMessage(Handler.java:92)
9   at  android.os.Looper.loop(Looper.java:154)
10  at  android.app.ActivityThread.main(ActivityThread.java:4945)
11  at  java.lang.reflect.Method.invokeNative(Native Method)
12  at  java.lang.reflect.Method.invoke(Method.java:511)
13  at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
14  at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
15  at  dalvik.system.NativeStart.main(Native Method)

我自己无法重现这个,所以我想知道是否有人可以告诉我问题可能是什么?

4

2 回答 2

3

不完全是您正在寻找的解决方案,但在使用 ACTION_PICK 意图选择应用程序时,同样的事情也发生在我身上。通常,会发生的情况是该活动需要很长时间才能无缘无故地启动,有时会因“未找到活动”异常而崩溃。我最终做的是建立自己的活动,列出可用的应用程序。在您的情况下,您可能可以对联系人执行相同的操作,使用光标查询所有带有电子邮件的联系人并显示对话框/活动以允许用户选择。听起来像一个糟糕的解决方法,但可能是最快的实现......(请参阅此处的示例代码)

另一种方法是联系这些用户,看看他们是否有可能不支持ContactsContract.CommonDataKinds.Email.CONTENT_URI内容类型的自定义联系人应用程序。

于 2013-08-04T09:59:25.123 回答
3

据我所知,问题是您假设每个用户都安装了一个可以响应您想要执行的操作数据组合的应用程序。虽然假设在您的情况下可能成立,但某些用户可能选择弄乱他们的系统,并可能安装了一个应用程序来管理他们无法响应您启动的操作的联系人。无论是什么原因,您都应该始终检查应用程序的可用性以响应您的Intent.

public static boolean isIntentAvailable(Context context, String action)
{
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List<ResolveInfo> list =
            packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

如果您作为参数true声明的至少一个应用程序可用,则此代码将返回。action有关我上面描述的问题的官方文档,请参阅Intents 和 Intent Filters

现在,这一切都很好,但它会解决什么问题?首先,您用户的应用程序不会崩溃。然后,您需要从无法继续进行的事实中恢复过来,因为您认为您可以。通常,向用户显示一条消息并建议他安装一个您知道可以提供该功能的应用程序效果很好。另外,我会在您的文档中注明这种依赖关系,以便您的所有用户都清楚他们需要什么。

更新:更多资源供您查看:

我相信后者可以准确解释您的应用程序崩溃的原因。我引用:

"Caution: If you invoke an intent and there is no app available on the device that can handle the intent, your app will crash."

该部分还包含有关如何处理该问题的更多信息。

于 2013-08-09T09:29:27.597 回答