Никакой активности не найдено для обработки Intent action.VIEW при нажатии ссылки по электронной почте

Я получил это новое исключение сбоя после новейшего обновления приложения. Кажется, это нигде не указывается. Кто-нибудь сможет рассказать, в чем проблема? Это похоже на возможную проблему с электронным форматированием из-за этого: dat = mailto: [email protected](имеет дополнительные функции).... но я не уверен, что у меня есть ошибки в электронных сообщениях.

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW
dat=mailto:[email protected] (has extras) }
        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1512)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1384)
        at android.app.Activity.startActivityForResult(Activity.java:3190)
        at android.app.Activity.startActivity(Activity.java:3297)
        at android.text.style.URLSpan.onClick(URLSpan.java:62)
        at android.text.method.LinkMovementMethod.onTouchEvent(LinkMovementMethod.java:212)
        at android.widget.TextView.onTouchEvent(TextView.java:8344)
        at android.view.View.dispatchTouchEvent(View.java:5542)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860)
        at android.view.View.dispatchPointerEvent(View.java:5722)
        at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2897)
        at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2473)
        at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
        at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2482)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4424)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
        at dalvik.system.NativeStart.main(Native Method)

Спасибо!

Вот файл манифеста:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mypackage"
    android:versionCode="123"
    android:versionName="1.2.3" >

    <supports-screens  android:largeScreens="true"   android:normalScreens="true"  android:smallScreens="true"/> 

    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="16"/>

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


    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />


    <permission android:name="com.problemio.permission.C2D_MESSAGE" 
        android:protectionLevel="signature" />
    <uses-permission android:name="com.problemio.permission.C2D_MESSAGE" />


    <!-- App receives GCM messages. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 


    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" 
        android:theme="@style/CustomTheme" 
        android:name="MyApplication"
                >

        <!--  For Google Cloud Messaging -->
        <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
          <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.problemio" />
          </intent-filter>
        </receiver>   

        <service android:name=".GCMIntentService" />
        <!--  End of Google Cloud Messaging -->






        <activity
            android:name=".ProblemioActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".AddProblemActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/add_problem" />

        <activity
            android:name=".LoginActivity"
            android:label="@string/login" />        

        <activity
            android:name=".MyProblemsActivity"
            android:label="@string/your_problems" /> 

        <activity
            android:name=".CreateProfileActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/create_account" />         

        <activity
            android:name=".ProblemActivity"
            android:label="@string/problem_page_header" />   


        <activity
            android:name=".WePromoteActivity"
            android:label="@string/we_promote" /> 

<!--  
        <activity
            android:name=".SuggestSolutionActivity"
            android:label="@string/suggest_solution_header" />  

        <activity
            android:name=".SuggestedSolutionActivity"
            android:label="@string/suggested_solution_header" />          

        <activity
            android:name=".ViewSolutionsActivity"
            android:label="@string/view_solutions_header" />        
-->        
        <activity
            android:name=".TopicActivity"
            android:label="@string/topic_header" 
            android:configChanges="keyboardHidden|orientation"
            android:windowSoftInputMode="stateHidden"/>         

        <activity
            android:name=".ForgotPasswordActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/forgot_password_heading" />         

        <activity
            android:name=".AskQuestionActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/ask_question_heading" />         

        <activity
            android:name=".QuestionActivity"
            android:label="@string/question_header" 
            android:configChanges="keyboardHidden|orientation"
            android:windowSoftInputMode="stateHidden"/>     


        <activity
            android:name=".MyQuestionsActivity"
            android:label="@string/see_my_questions_header" />        



        <activity
            android:name=".LearnActivity"
            android:label="@string/learn_header" />         

        <activity
            android:name=".ExtraHelpActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/extra_help_header" />          

        <activity
            android:name=".content.AdvertisingActivity"
            android:label="@string/advertising_header" />           

        <activity
            android:name=".content.ProductStrategyActivity"
            android:label="@string/product_strategy_header" />         

        <activity
            android:name=".content.BusinessModelsActivity"
            android:label="@string/business_models_header" />           

        <activity
            android:name=".content.StageTacticsActivity"
            android:label="@string/stage_tactics_header" />         

        <activity
            android:name=".content.InvestorsActivity"
            android:label="@string/funding_header" />         


        <activity
            android:name=".content.TargetMarketActivity"
            android:label="@string/target_market_header" />           

        <activity
            android:name=".SettingsActivity"
            android:label="@string/settings_header" />         

        <activity
            android:name=".content.BusinessIdeasActivity"
            android:label="@string/business_ideas" /> 

        <activity
            android:name=".content.MarketIdeaValidationActivity"
            android:label="@string/market_idea_validation" />         



        <activity
            android:name=".content.UnitEconomicsActivity"
            android:label="@string/unit_economics" />  

        <activity
            android:name=".content.PremiumWebAdvertisingActivity"
            android:label="@string/premium_web_marketing" />          

        <activity
            android:name=".content.PsychologyActivity"
            android:label="@string/business_psychology" />  

        <activity
            android:name=".NumberOfBusinessesActivity"
            android:label="@string/num_of_businesses" />          

        <activity
            android:name=".TimelineActivity"
            android:label="@string/timeline" />          

        <activity
            android:name=".content.PitchBusinessActivity"
            android:label="@string/pitch" />   

        <activity
            android:name=".content.TopMistakesActivity"
            android:label="@string/top_mistakes" />        

        <activity
            android:name=".content.MarktingAndConversionActivity"
            android:label="@string/marketing_and_conversion" />           

        <activity
            android:name=".content.HelpInstructionsActivity"
            android:label="@string/help_instructions" />          


        <activity
            android:name=".content.WebSetupActivity"
            android:label="@string/web_setup_page" />          


        <activity
            android:name=".UpdateProfileActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/update_profile" />           





        <activity
            android:name=".FeedbackActivity"
            android:label="@string/feedback" 
            android:configChanges="keyboardHidden|orientation"
            android:windowSoftInputMode="stateHidden"/> 


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

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

        <activity
            android:name=".EditBusinessActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/edit_business" />   

        <activity
            android:name=".TopicEditActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/topic_edit" />        

        <activity
            android:name=".InviteFriendsActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/invite_friends" />

        <activity
            android:name=".EnterInviteCodeActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/enter_invite_code" />        

        <activity
            android:name=".CommunityActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/community_page" />   

        <activity
            android:name=".CommunitySignupActivity"
            android:label="@string/community_signup" />           

        <activity
            android:name=".PlanExamplesActivity"
            android:label="@string/plan_examples" />

        <activity
            android:name=".Settings"
            android:label="@string/plan_examples" />        


        <activity
            android:name=".GiveBackActivity"
            android:label="@string/give_back" /> 

        <activity
            android:name=".MotivationActivity"
            android:label="@string/motivation_page" />         


        <activity
            android:name=".AdsActivity"
            android:label="@string/ads_activity" />         

        <activity
            android:name=".content.WebsiteServiceActivity"
            android:label="@string/website_service_activity" />         

        <activity
            android:name=".MoreArticlesActivity"
            android:label="@string/more_articles" />           

<!--         
        <service android:name="BillingService" />

        <receiver android:name="BillingReceiver">
            <intent-filter>
                <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
                <action android:name="com.android.vending.billing.RESPONSE_CODE" />
                <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
            </intent-filter>
        </receiver>        
 -->

        <activity android:name="com.tapjoy.TJCOffersWebView" android:configChanges="keyboardHidden|orientation" />
        <activity android:name="com.tapjoy.TapjoyFullScreenAdWebView" android:configChanges="keyboardHidden|orientation" />
        <activity android:name="com.tapjoy.TapjoyDailyRewardAdWebView" android:configChanges="keyboardHidden|orientation" />
        <activity android:name="com.tapjoy.TapjoyVideoView" android:configChanges="keyboardHidden|orientation" />

        </application>

</manifest>

Может ли быть что-то вроде этого:

<TextView
    android:id="@+id/contact_email"    
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop ="15dp" 
    android:autoLink="email"
    android:text="[email protected]"

    />

Ответ 1

Скопировано из моего другого ответа

У меня уже была такая же проблема, и я решил ее, создав новый класс, который проверяет null, прежде чем запускать Intent.

Все, что вам нужно сделать, это заменить все теги URLSpan перед установкой текста TextView (что означает, что вы не можете использовать setAutoLinkMask()).

Это нужно сделать, потому что метод URLSpan onClick() не выполняет никаких проверок null.

Как преуспеть:

TextView txt = ...
txt.setLinksClickable(true);
txt.setText(SafeURLSpan.parseSafeHtml(<<YOUR STRING GOES HERE>>));
txt.setMovementMethod(LinkMovementMethod.getInstance());

Виды строк, которые можно использовать в <<YOUR STRING GOES HERE>>:

"Click here: <a href=\"http://google.com\">My links</a>"
"Mail me: <a href=\"mailto:[email protected]\">My email</a>"
... and so on...

Вот источник для класса SafeURLSPan (я использую его в своем приложении FPlay, и он был протестирован на Android 10 +):

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Browser;
import android.text.Html;
import android.text.Spannable;
import android.text.style.URLSpan;
import android.view.View;

public final class SafeURLSpan extends URLSpan {
    public SafeURLSpan(String url) {
        super(url);
    }

    @Override
    public void onClick(View widget) {
        try {
            final Uri uri = Uri.parse(getURL());
            final Context context = widget.getContext();
            final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            if (context != null && intent != null) {
                intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
                context.startActivity(intent);
            }
        } catch (Throwable ex) {
        }
    }

    public static CharSequence parseSafeHtml(CharSequence html) {
        return replaceURLSpans(Html.fromHtml(html.toString()));
    }

    public static CharSequence replaceURLSpans(CharSequence text) {
        if (text instanceof Spannable) {
            final Spannable s = (Spannable)text;
            final URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
            if (spans != null && spans.length > 0) {
                for (int i = spans.length - 1; i >= 0; i--) {
                    final URLSpan span = spans[i];
                    final int start = s.getSpanStart(span);
                    final int end = s.getSpanEnd(span);
                    final int flags = s.getSpanFlags(span);
                    s.removeSpan(span);
                    s.setSpan(new SafeURLSpan(span.getURL()), start, end, flags);
                }
            }
        }
        return text;
    }
}

Ответ 2

Я столкнулся с этой проблемой, дело в том, что когда вы определяете:

android:autoLink="email"
android:text="[email protected]"

или любой другой тип автолинка в TextView, android обрабатывает все для вас.

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

Я не знаю, что вы можете сделать, чтобы обойти эту проблему. Я предполагаю, что небезопасно предположить, что у пользователя есть настройка почты или хотя бы одно приложение, способное справиться с этим намерением. Я также предполагаю, что приложение не должно терпеть крах... Я думаю, что это проблема с Android, так как в этом случае у вас нет способа обработать исключение.

Если вы посмотрите на источник URLSpan (если установлена ​​автозагрузка, TextView использует android.text.util.Linkify.addLinks(..), который создает экземпляры URLSpan для создания ссылок): http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.2_r1/android/text/style/URLSpan.java#URLSpan

public void onClick(View widget) {
    Uri uri = Uri.parse(getURL());
    Context context = widget.getContext();
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
    context.startActivity(intent);
}

Они могут обрабатывать исключение или использовать PackageManager, чтобы определить, будет ли Intent успешным до вызова startActivity() (например, они рекомендуют: http://developer.android.com/training/basics/intents/sending.html#Verify) или использовать Chooser.

Хотя платформа Android гарантирует, что определенные намерения будут разрешены для одного из встроенных приложений (например, для приложения "Телефон", "Электронная почта" или "Календарь" ), вы должны всегда включать в себя этап проверки перед вызовом намерения.

Внимание: если вы вызываете намерение и на устройстве нет приложения, которое может справиться с намерением, ваше приложение будет аварийно.

Итак, мой вопрос: есть ли гарантия того, что намерение электронной почты всегда будет разрешено на реальном устройстве?

ok... в том же разделе они также упоминают:

Примечание. Вы должны выполнить эту проверку, когда ваша деятельность начнется сначала, если вам нужно отключить функцию, которая использует намерение, прежде чем пользователь попытается ее использовать. Если вы знаете о конкретном приложении, которое может обрабатывать намерение, вы также можете предоставить ссылку для пользователя для загрузки приложения (см. Ссылку на ваш продукт в Google Play).

Всегда можно проверить, разрешено ли намерение какой-либо активности в начале приложения, установить флаг и каждый раз, когда макет, содержащий такой TextView, раздувается, мы находим его и отключая автоматическую ссылку для электронной почты и т.д. (и это когда я размышляю над убийством единорога над кодированием, что)

Ответ 3

Кстати, никакой почтовый клиент не может возникнуть, если на устройстве не настроена учетная запись электронной почты, поэтому технически это может произойти и на реальных устройствах. Вот код для отключения AutoLink, если он недоступен, как предложено novettam:

protected boolean checkIntent(Intent intent)
{
    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> apps = packageManager.queryIntentActivities(intent, 0);
    return apps.size() > 0 && !( apps.get(0).activityInfo.name.equals(activity.getClass().getName()) && apps.size() == 1) ;
}


protected Intent createDummyEmailIntent()
{
    final Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto", "[email protected]", null));
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "EXTRA_SUBJECT");
    return emailIntent;
}

protected Intent createDummyWebIntent()
{
    final Intent webIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("http://www.google.co.uk"));
    return webIntent;
}

protected Intent createDummyPhoneIntent(){
    String uri = "tel:" + "0131 666 7777".trim() ;
    final Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
    phoneIntent.setData(Uri.parse(uri));
    return phoneIntent;
}
//Checking
if ( !checkIntent(intent) ) {
            textview.setAutoLinkMask(0);
}
//be sure that you call setText after this