Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to catch up exception when user click links in textview?

Tags:

android

use a TextView to show email, and set


TextView tvEmail = (TextView)this.findViewById(R.id.tvEmail);
Linkify.addLinks(tvEmail, Linkify.EMAIL_ADDRESSES);

click on above mail address will raise an exception, because mail client didn't found. how to catch up this exception?

like image 219
Cooper.Wu Avatar asked Dec 28 '25 04:12

Cooper.Wu


1 Answers

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: <a href=\"http://google.com\">My links</a>"
"Mail me: <a href=\"mailto:[email protected]\">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;

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;
    }
}
like image 150
carlosrafaelgn Avatar answered Dec 30 '25 20:12

carlosrafaelgn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!