Skip to content Skip to sidebar Skip to footer

No Activity Found To Handle Intent Action.view When Clicking Email Link

I got this new crash exception after the newest app update. It seems to not point anywhere. Would anyone be able to tell what the issue is? It looks like a possible email-formatti

Solution 1:

Copied from my other answer

I have already had the same issue, and I solved it by creating a new class that checks for null before actually launching the Intent.

All you have to do is to replace all URLSpan spans, before setting the TextView's text (which means you cannot use setAutoLinkMask()).

This has to be done, because URLSpan's onClick() method does not perform any kind of null checks.

How to preceed:

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

Kinds of strings that could be used in <<YOUR STRING GOES HERE>>:

"Click here: <ahref=\"http://google.com\">My links</a>"
"Mail me: <ahref=\"mailto:john@doe.com\">My email</a>"
... and so on...

Here is the source for SafeURLSPan class (I use it in my app FPlay, and it has been tested on 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;

publicfinalclassSafeURLSpanextendsURLSpan {
    publicSafeURLSpan(String url) {
        super(url);
    }

    @OverridepublicvoidonClick(View widget) {
        try {
            finalUriuri= Uri.parse(getURL());
            finalContextcontext= widget.getContext();
            finalIntentintent=newIntent(Intent.ACTION_VIEW, uri);
            if (context != null && intent != null) {
                intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
                context.startActivity(intent);
            }
        } catch (Throwable ex) {
        }
    }

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

    publicstatic CharSequence replaceURLSpans(CharSequence text) {
        if (text instanceof Spannable) {
            finalSpannables= (Spannable)text;
            final URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
            if (spans != null && spans.length > 0) {
                for (inti= spans.length - 1; i >= 0; i--) {
                    finalURLSpanspan= spans[i];
                    finalintstart= s.getSpanStart(span);
                    finalintend= s.getSpanEnd(span);
                    finalintflags= s.getSpanFlags(span);
                    s.removeSpan(span);
                    s.setSpan(newSafeURLSpan(span.getURL()), start, end, flags);
                }
            }
        }
        return text;
    }
}

Solution 2:

I ran into this problem as well, the thing is that when you define:

android:autoLink="email"android:text="some@email.com"

or any other type of autolink in a TextView, android handles everything for you.

In the emulator email is not setup by default, so there is no app to handle the intent, and this makes your app crash if you click an autolinked email address. If you open the mail app and follow the instructions to set it up, then when you click the email address it will work.

I don't know what you can do to work around this issue. I guess it might not be safe to assume the user has mail setup or at least one app capable of handling that intent. I also guess that the app shouldn't be crashing... I think this is an issue with android as in this case you have no way of handling the exception.

If you look at the source of URLSpan (If autolink is set, TextView uses android.text.util.Linkify.addLinks(..) which creates instances of URLSpan to create links): http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.2_r1/android/text/style/URLSpan.java#URLSpan

publicvoidonClick(View widget) {
    Uriuri= Uri.parse(getURL());
    Contextcontext= widget.getContext();
    Intentintent=newIntent(Intent.ACTION_VIEW, uri);
    intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
    context.startActivity(intent);
}

They could either handle the exception or use PackageManager to determine if the Intent would succeed before calling startActivity() (like they recommend: http://developer.android.com/training/basics/intents/sending.html#Verify) or use a chooser.

Although the Android platform guarantees that certain intents will resolve to one of the built-in apps (such as the Phone, Email, or Calendar app), you should always include a verification step before invoking an intent.

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

So my question would be: is there any guarantee that an email intent will always resolve on a real device?

ok... on the same section they also mention:

Note: You should perform this check when your activity first starts in case you need to disable the feature that uses the intent before the user attempts to use it. If you know of a specific app that can handle the intent, you can also provide a link for the user to download the app (see how to link to your product on Google Play).

One can always check if the intent resolves to any activity at the start of the application, set a flag and every time the layout containing such TextView is inflated we find it and disable auto link for email, etc. (and this is when I ponder killing an unicorn over coding that)

Solution 3:

By the way no email client can occur if no email account is set up on the device so technically this can occur on real devices as well. Here is the code for disabling the AutoLink if not available as suggested by novettam:

protectedbooleancheckIntent(Intent intent)
{
    PackageManagerpackageManager= 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()
{
    finalIntentemailIntent=newIntent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto", "abc@gmail.com", null));
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "EXTRA_SUBJECT");
    return emailIntent;
}

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

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

Post a Comment for "No Activity Found To Handle Intent Action.view When Clicking Email Link"