5

Phones with SDK 20+ think that any two words with a dot between them is a link. How can I make my own Link detector?

android:autoLink="web" thinks abra.kadabra is an url.

setAutoLinkMask(Linkify.WEB_URLS); thinks abra.kadabra is an url.

Phones with SDK < 20 link everything correctly, the error happens only on when SDK is 20+.

Examples of what I've tried:

Code happening inside my custom TextView

SpannableString ss = new SpannableString(this.getText().toString());    
//LinkManager is a copy of Linkify but with another pattern.       
LinkManager.addLinks(ss, LinkManager.WEB_URLS);   
setText(ss);            
setMovementMethod(LinkMovementMethod.getInstance());   
setWebLinksTouchFeedback();

This didn't linkify anything. Even when I use Linkify instead of LinkManager

I have tried many other solutions, all which end up in linking nothing or everything. Any solution out there?

Sergio Moura
  • 4,888
  • 1
  • 21
  • 38
pv-gni
  • 51
  • 2
  • thing is, `abra.kadabra` could well be an url (it is not. today.). There are a bunch of TLDs now. – njzk2 May 29 '15 at 21:20

2 Answers2

3

You can make your own link detector using Matcher and Pattern classes and make them clickable with ClickableSpan.

String text = textView.getText().toString();

int i=0;
SpannableString spannableString = new SpannableString(text);
Matcher urlMatcher = Patterns.WEB_URL.matcher(text);
while(urlMatcher.find()) {
    String url = urlMatcher.group(i);
    int start = urlMatcher.start(i);
    int end = urlMatcher.end(i++);
    spannableString.setSpan(new GoToURLSpan(url), start, end, 0);
}

textView.setText(spannableString);
textView.setMovementMethod(new LinkMovementMethod());    

private static class GoToURLSpan extends ClickableSpan {
    String url;

    public GoToURLSpan(String url){
        this.url = url;
    }

    public void onClick(View view) {
        Uri webPage = Uri.parse(url); //http:<URL> or https:<URL>
        Intent intent = new Intent(Intent.ACTION_VIEW, webPage);
        view.getContext().startActivity(intent);
    }
}

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/text"
    android:text="Link http://google.com but dont link abra.kadabra"
    android:textColorLink="@color/accent"
    android:textColorHighlight="@color/accent" />

Replace Pattern.WEB_URL with your own. You can find some url patterns in StackOverflow.

Pedro
  • 391
  • 1
  • 8
0

I fixed it myself by calling this method before the super method of the setText since all texts I want to linkify are set dynamically.

private void linkifyTexts(CharSequence charsequence)
{
    String text = charsequence.toString();
    String[] parts = text.split("\\s+");
    for (int i = 0; i < parts.length; i++)
    {
        boolean isUrl = isURLValid(parts[i]);
        if (isUrl)
        {
            setAutoLinkMask(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES);
            setWebLinksTouchFeedback();
            break;
        }
    }
}

public boolean isURLValid(String url)
{
    Pattern p = Pattern.compile(getContext().getString(R.string.url_pattern));
    return p.matcher(url).matches();
}

with a custom pattern for urls I want to accept. Thanks for the assistance, I appreciate it.

pv-gni
  • 51
  • 2