Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception occurs for some users with email contact picker

Tags:

android

I am trying to allow my users to select a contact from among their contacts that have email addresses. This is the code that is executed when they click the appropriate button:

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

This is working just fine on my own phone, but after releasing my app I'm seeing the following exception occur for some of my users:

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)

I haven't been able to reproduce this myself so I'm wondering if anyone could tell me what the problem may be?

like image 519
Catherine Avatar asked Nov 28 '12 20:11

Catherine


2 Answers

Not exactly the solution you are looking for but the same thing used to happen for me too when using the ACTION_PICK intent to select an application. Usually, what would happen is that the activity would take a long time to launch for no (apparent) reason and sometimes just crash with "No Activity Found" exception. What I ended up doing is building my own activity that lists the available apps. In your case, you could probably do the same for contacts using a cursor to query all the contacts with email and showing a dialog/activity to allow user selection. Sounds like an awful workaround but might be the fastest to implement... (See sample code here)

Another way to go, would be to contact those users and see if they have a custom contacts app that might not support the ContactsContract.CommonDataKinds.Email.CONTENT_URI content type.

like image 123
Muzikant Avatar answered Nov 05 '22 15:11

Muzikant


The problem as far as I can see is that you are assuming that every user has an application installed that can respond to the action-data combination you want to perform. While the assumption is likely to hold true in your case, some users might have chosen to mess with their system and could have installed an application to manage their contacts that cannot respond to the action you launch. Whatever the reason, you should always check for the availability of an application to respond to your 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;
}

This code will return true if at least one application is available that you have stated as the action parameter. See Intents and Intent Filters for the official documentation on the problem I described above.

Now, this is all good and fine but what will it solve? First, your user's application will not crash. You then need to recover from the fact that you cannot proceed as you have thought you could. Usually, displaying a message to the user and proposing that he install an application that you know provides the functionality works rather well. Also, I'd note this dependency in your documentation so that it is clear to all your users what they need.

Update: More sources for you to look at:

  • Intent Matching
  • Sending the User to Another App

I believe the latter holds the exact explanation as to why your application crashes. I quote:

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

That section also holds more information on how to deal with the issue.

like image 27
Eric Tobias Avatar answered Nov 05 '22 16:11

Eric Tobias