androidandroid-4.2-jelly-bean

ActivityNotFoundException exception on Jelly Bean for Gmail composer


This class works fine on ICS, but fails with ActivityNotFoundException on Jelly Bean. Do you guys know why? Thank you.

public class EmailSender {

    public static Intent getSendEmailIntent(Context context, String email,
                                            String subject, String body, File fileName, String chooserTitle) {

        final Intent emailIntent = new Intent(
                android.content.Intent.ACTION_SEND);

        //Explicitly only use Gmail to send
        emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");

        emailIntent.setType("plain/text");

        //Add the recipients
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
                new String[]{email});

        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);

        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);

        //Add the attachment by specifying a reference to our custom ContentProvider
        //and the specific file of interest
        emailIntent.putExtra(
                Intent.EXTRA_STREAM,
                Uri.fromFile(fileName));

        return emailIntent;
    }
}

On Jelly Bean I'm getting an exception:

11-19 15:32:07.852: E/AndroidRuntime(19630): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.google.android.gm/com.google.android.gm.ComposeActivityGmail}; have you declared this activity in your AndroidManifest.xml?

Full trace in case of need:

11-19 15:32:07.852: E/AndroidRuntime(19630): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.google.android.gm/com.google.android.gm.ComposeActivityGmail}; have you declared this activity in your AndroidManifest.xml? 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1618) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1417) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.app.Activity.startActivityForResult(Activity.java:3370) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.app.Activity.startActivityForResult(Activity.java:3331) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:701) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.support.v4.app.Fragment.startActivity(Fragment.java:787) 11-19 15:32:07.852: E/AndroidRuntime(19630): at ebeletskiy.gmail.com.passwords.ui.Export.sendByEmail(Export.java:91) 11-19 15:32:07.852: E/AndroidRuntime(19630): at ebeletskiy.gmail.com.passwords.ui.Export.access$400(Export.java:22) 11-19 15:32:07.852: E/AndroidRuntime(19630): at ebeletskiy.gmail.com.passwords.ui.Export$1.onClick(Export.java:57) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.view.View.performClick(View.java:4202) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.view.View$PerformClick.run(View.java:17340) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.os.Handler.handleCallback(Handler.java:725) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.os.Handler.dispatchMessage(Handler.java:92) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.os.Looper.loop(Looper.java:137) 11-19 15:32:07.852: E/AndroidRuntime(19630): at android.app.ActivityThread.main(ActivityThread.java:5039) 11-19 15:32:07.852: E/AndroidRuntime(19630): at java.lang.reflect.Method.invokeNative(Native Method) 11-19 15:32:07.852: E/AndroidRuntime(19630): at java.lang.reflect.Method.invoke(Method.java:511) 11-19 15:32:07.852: E/AndroidRuntime(19630): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 11-19 15:32:07.852: E/AndroidRuntime(19630): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 11-19 15:32:07.852: E/AndroidRuntime(19630): at dalvik.system.NativeStart.main(Native Method)


Solution

  • I'd advise against using an intent to directly open the gmail compose activity. Using such a strict intent means that the user needs to have gmail installed to use your app. Not everybody uses gmail for their mail client.. Additionally, by hardcoding class names you leave yourself open to instances where the class name changes can result in your activity breaking (which is the cause of your current problem)

    I decompiled the gmail 4.2 application and found that the ComposeActivity class name and path has changed.. it is now com.android.mail.compose.ComposeActivity

    You should use a general email intent that allows the user to use the email application of their choosing