How to catch an Exception (ActivityNotFoundException) while using LinkMovementMethod
Asked Answered
V

2

6

I have currently a TextView with some HTML phone numbers and url.

I have noticed that we can use the setMovementMethod to make these links clickable:

tv.setText("Phone number is: +32485123456 and url is http://www.blabla.com");
tv.setMovementMethod(LinkMovementMethod.getInstance());

This works pretty well, but on some devices, it crash with ActivityNotFoundException and that is quite understanble. (see code below)

These problems appear in my developer console and I cannot reproduce them.

The big problem I am facing is that I cannot try/catch code in my activity as the click is handled by LinkMovementMethod

Any idea on how I can avoid such errors?

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=www.vlaamsbrabant.be/zoutleeuw (has extras) }
    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1408)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)
    at android.app.Activity.startActivityForResult(Activity.java:2817)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:817)
    at android.app.Activity.startActivity(Activity.java:2923)
    at android.text.style.URLSpan.onClick(URLSpan.java:62)
    at android.text.method.LinkMovementMethod.onTouchEvent(LinkMovementMethod.java:216)
    at android.widget.TextView.onTouchEvent(TextView.java:6788)
    at android.view.View.dispatchTouchEvent(View.java:3766)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1896)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1159)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1880)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1811)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    at dalvik.system.NativeStart.main(Native Method)
Violet answered 10/2, 2013 at 9:48 Comment(0)
M
20

You can always just extend LinkMovementMethod and catch the error there.

Something like:

private class MovementCheck extends LinkMovementMethod {

    @Override
    public boolean onTouchEvent( TextView widget, Spannable buffer, MotionEvent event ) {
        try {
            return super.onTouchEvent( widget, buffer, event ) ;
        } catch( Exception ex ) {
            Toast.makeText( MainActivity.this, "Could not load link", Toast.LENGTH_LONG ).show();
            return true;
        }
    }

}

Will display an error message in the case that there is no application setup to handle the intent.

Another option is to use the method in this question to determine ahead of time if anything is prepared to handle your links.

Madox answered 29/4, 2013 at 22:21 Comment(3)
Not tested yet but definitely sound like a perfect answer! Answer accepted!Violet
Use it like this:- setMovementMethod( new MovementCheck() );Tiphani
Or use it like this. Add: private static MovementCheck sInstance; public static MovementCheck getInstance() { if (sInstance == null) sInstance = new MovementCheck (); return sInstance; } Also, context can be obained from TextView: widget.getContext();Radbun
M
0

If your textview his origin is in xml you can try an aproach defined here.
Maby (I am almost sure of it.) but will the OS handle this for u.

If this doesnt work, then you must write device independ code for tablets and for phones. In this case, maby that this post wil guide you. When its a Phone you will allow the linking and else you wont.

Maby seperating the 2 links in 2 textviews because the os can either way do one of the link (website) thats way it prob makes it clickable and crashes when you try to click the phonenumber one

Hope this helps.

Mccants answered 26/4, 2013 at 13:9 Comment(3)
ALso crash if set in xml, and it crash on some phones too (even url crash)Violet
or maby seperating the phone number and url in 2 textviewsMccants
Sorry, but GalaJon answer looks like the solution I was looking for.Violet

© 2022 - 2024 — McMap. All rights reserved.