3

I am using android:autoLink set to web on a TextView in my Android app to enable clickable links. But if I run this on my HTC Desire S upgraded to ICS, when I tap on one of the links I get the following exception

android.content.ActivityNotFoundException: Unable to find explicit activity class 
  {com.htc.HtcLinkifyDispatcher/
  com.htc.HtcLinkifyDispatcher.HtcLinkifyDispatcherActivity}; 
  have you declared this activity in your AndroidManifest.xml?

    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1634)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1510)
    at android.app.Activity.startActivityFromChild(Activity.java:3519)
    at android.app.Activity.startActivityForResult(Activity.java:3271)
    at android.app.Activity.startActivity(Activity.java:3358)
    at woodsie.avalanche.info.InfoActivity.startActivity(InfoActivity.java:61)
    at android.text.style.LinkifyURLSpan.onClick(LinkifyURLSpan.java:73)

Attempts to register HtcLinkifyDispatcherActivityget me nowhere as the class is not on my build path.

James Woods
  • 477
  • 1
  • 4
  • 15
  • [Issue 39682](https://code.google.com/p/android/issues/detail?id=39682) seems to be the relevant bug report for the problem. – JJD Nov 25 '13 at 15:48

1 Answers1

11

The best article I found relating to this was The Linkify Problem: The Detection and the Mitigation.

But, rather than trying to intercept and replace the URLSpan class, I went a level lower and overrode the startActivity() on the parent Activity of the TextView.

@Override
public void startActivity(Intent intent) {
    try {
        /* First attempt at fixing an HTC broken by evil Apple patents. */
        if (intent.getComponent() != null 
                && ".HtcLinkifyDispatcherActivity".equals(intent.getComponent().getShortClassName()))
            intent.setComponent(null);
        super.startActivity(intent);
    } catch (ActivityNotFoundException e) {
        /*
         * Probably an HTC broken by evil Apple patents. This is not perfect,
         * but better than crashing the whole application.
         */
        super.startActivity(Intent.createChooser(intent, null));
    }
}

Hacky but simple, and seems to work.

James Woods
  • 477
  • 1
  • 4
  • 15
  • 1
    It will only work if that is how you are starting the activity. Since any `Context` can start the activity, developers could conceivably use some other context (e.g., the `getApplicationContext()` junk that floods teh Interwebs). I am also a bit nervous that `createChooser()` will consistently ignore the component already specified in the `Intent` -- I would recommend calling `setComponent(null)` to clear that out. – CommonsWare Dec 04 '12 at 12:04
  • As I will be the only developer working on this little app, and I don't expect to be doing anything fancier than `autolink`, this should be a reasonable workaround for me. – James Woods Dec 09 '12 at 10:10
  • I had a bit more of a play around with it and calling `setComponent(null)` before calling `startActivity()` makes things even better. It gets rid of the evil `HtcLinkifyDispatcher` completely, starting the default browser as expected without showing the chooser. I have updated the code sample in my answer to reflect my super safe implementation. – James Woods Dec 09 '12 at 10:12