我正在尝试允许我的用户从具有电子邮件地址的联系人中选择联系人。这是单击相应按钮时执行的代码:
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)
我自己无法重现这一点,所以我想知道是否有人能告诉我这可能是什么问题?
答案 0 :(得分:3)
不完全是您正在寻找的解决方案,但在使用ACTION_PICK意图选择应用程序时,我也会遇到同样的事情。 通常,会发生的事情是,由于没有(明显的)原因,活动需要很长时间才能启动,有时只会因“找不到活动”异常而崩溃。 我最终做的是建立自己的活动,列出可用的应用程序。 在您的情况下,对于使用光标查询所有联系人和电子邮件并显示允许用户选择的对话/活动的联系人,您可能也会这样做。 听起来像一个糟糕的解决方法,但可能是最快的...(参见示例代码here)
另一种方法是与这些用户联系,看看他们是否有可能不支持ContactsContract.CommonDataKinds.Email.CONTENT_URI
内容类型的自定义联系人应用。
答案 1 :(得分: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 and 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."
该部分还提供了有关如何处理该问题的更多信息。