Попытка отправить электронное письмо вызывает исключение ActivityNotFoundException или PermissionDenial.

Я пытаюсь отправить электронное письмо с помощью ComposeActivityGmail. Я пробовал 3 подхода. Первый — самый простой Intent.setClassName:

sendIntent.setComponent( new ComponentName( "com.google.android.gm", "ComposeActivityGmail" ) );

При этом у меня есть следующее исключение:

java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW [email protected] cmp=com.google.android.gm/.ComposeActivityGmail (has extras) } from ProcessRecord{30a898b6 10871:org.madebyalex.myperiod/u0a255} (pid=10871, uid=10255) not exported from uid 10067
   at android.os.Parcel.readException(Parcel.java:1546)
   at android.os.Parcel.readException(Parcel.java:1499)
   at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2468)
   at android.app.Instrumentation.execStartActivity(Instrumentation.java:1563)
   at android.app.Activity.startActivityForResult(Activity.java:3755)
   at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
   at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:77)
   at android.app.Activity.startActivityForResult(Activity.java:3716)
   at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
   at android.app.Activity.startActivity(Activity.java:4036)
   at android.app.Activity.startActivity(Activity.java:3998)
   at org.madebyalex.myperiod.EmailMessage.sendMessage(EmailMessage.java:93)
   at org.madebyalex.myperiod.SecurityFragment$2.onClick(SecurityFragment.java:159)
   at android.view.View.performClick(View.java:4785)
   at android.view.View$PerformClick.run(View.java:19884)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5343)
   at java.lang.reflect.Method.invoke(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

Второй подход основан на этом вопросе с использованием PackageManager:

Intent sendIntent = new Intent( Intent.ACTION_VIEW );
    sendIntent.setType( "plain/text" );
    sendIntent.setData( Uri.parse( receivers.get( 0 ) ) );

    final PackageManager packageManager = context.getPackageManager();
    final List<ResolveInfo> matches = packageManager.queryIntentActivities( sendIntent, 0 );
    String className = "";

    for( ResolveInfo info : matches ){
        if( info.activityInfo.packageName.equals( "com.google.android.gm" ) ){
            className = info.activityInfo.name;
            if( className != null && !className.isEmpty() ){
                break;
            }
        }
    }

    sendIntent.setClassName( "com.google.android.gm", className );
    Log.e("ERROR", "CLASS NAME: "+className);

    sendIntent.putExtra( Intent.EXTRA_SUBJECT, getSubject() );
    sendIntent.putExtra( Intent.EXTRA_TEXT, message+"\n" );
    context.startActivity( sendIntent );

При таком подходе возникает следующее исключение:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.google.android.gm/ComposeActivityGmail}; have you declared this activity in your AndroidManifest.xml?
   at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1868)
   at android.app.Instrumentation.execStartActivity(Instrumentation.java:1568)
   at android.app.Activity.startActivityForResult(Activity.java:3755)
   at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
   at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:77)
   at android.app.Activity.startActivityForResult(Activity.java:3716)
   at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
   at android.app.Activity.startActivity(Activity.java:4036)
   at android.app.Activity.startActivity(Activity.java:3998)
   at org.madebyalex.myperiod.EmailMessage.sendMessage(EmailMessage.java:93)
   at org.madebyalex.myperiod.SecurityFragment$2.onClick(SecurityFragment.java:159)
   at android.view.View.performClick(View.java:4785)
   at android.view.View$PerformClick.run(View.java:19884)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5343)
   at java.lang.reflect.Method.invoke(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

И с помощью этого кода возникает то же самое исключение, что и выше:

sendIntent.setComponent( new ComponentName( "com.google.android.gm", "ComposeActivityGmail" ) );

Некоторые ответы на SO говорят, что нужно объявить эту активность в манифесте Android. При этом AndroidStudio жалуется на часть «android.gm/ComposeActivityGmail»:

<activity
    android:name="com.google.android.gm/ComposeActivityGmail"
    android:screenOrientation="locked"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
    </intent-filter>
</activity>

Вставка этого простого кода в AndroidManifest.xml AndroidStudio жалуется: неразрешенный класс.

<activity android:name=".ComposeActivityGmail"/>

Как решить эту проблему, если все эти решения не работают?


person learner    schedule 25.11.2016    source источник
comment
Вы решили эту проблему?   -  person Nivedh    schedule 07.12.2016
comment
@Nivedh Да, но не используя ни одно из предложенных решений. Я использовал Intent.createChooser   -  person learner    schedule 07.12.2016
comment
Итак, выбор придет правильно? Он не будет направлять прямо на Gmail.   -  person Nivedh    schedule 09.12.2016


Ответы (3)


android.content.ActivityNotFoundException: невозможно найти явный класс активности {com.google.android.gm/ComposeActivityGmail}; декларировали ли вы это действие в файле AndroidManifest.xml?

объявите свою активность в манифесте и добавьте разрешение на доступ в Интернет, например

<manifest xlmns:android...>
 ...
 <uses-permission android:name="android.permission.INTERNET" />
 <application ...

<activity android:name=".ComposeActivityGmail"/>

</manifest>
person Community    schedule 25.11.2016

Попробуй это. Меня устраивает.

Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/html");
        emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { Constants.CONTACT_EMAIL_ADDRESS });
        final PackageManager pm = this.getPackageManager();
        final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
        String className = null;
        for (final ResolveInfo info : matches) {
            if (info.activityInfo.packageName.equals("com.google.android.gm")) {
                className = info.activityInfo.name;

                if(className != null && !className.isEmpty()){
                    break;
                }
            }
        }

        emailIntent.setClassName("com.google.android.gm", className);

        try {
            startActivity(emailIntent);
        } catch(ActivityNotFoundException ex) {
            // handle error
        }
person proy31    schedule 28.11.2016
comment
Этот код является небольшой модификацией кода, который я показал. - person learner; 28.11.2016
comment
У меня было то же исключение, что и у вас, и при использовании моего фрагмента это сработало. Если вы попробовали фрагмент, показанный выше, и если он не работает, пожалуйста, укажите. - person proy31; 28.11.2016

После нового обновления Gmail Google изменил название активности создания. Поэтому вместо того, чтобы указывать статическое значение, используйте приведенный ниже код для решения вашей проблемы.

Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/html");
        final PackageManager pm = this.getPackageManager();
        final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
        String className = null;
        for (final ResolveInfo info : matches) {
            if (info.activityInfo.packageName.equals("com.google.android.gm")) {
                className = info.activityInfo.name;

                if(className != null && !className.isEmpty()){
                    break;
                }
            }
        }
        emailIntent.setClassName("com.google.android.gm", className);
person Smeet    schedule 01.12.2016