obsłużyć kliknięcie linku Textview w mojej aplikacji na Androida

148

Obecnie renderuję dane wejściowe HTML w TextView w następujący sposób:

tv.setText(Html.fromHtml("<a href='test'>test</a>"));

Wyświetlany kod HTML jest dostarczany za pośrednictwem zewnętrznego zasobu, więc nie mogę zmieniać rzeczy tak, jak chcę, ale mogę oczywiście zmodyfikować kod HTML, aby zmienić wartość href, powiedzmy, na coś innego.

Chcę mieć możliwość obsługi kliknięcia łącza bezpośrednio w aplikacji, zamiast otwierania go w oknie przeglądarki. Czy jest to w ogóle możliwe? Domyślam się, że byłoby możliwe ustawienie protokołu wartości href na coś takiego jak „myApp: //”, a następnie zarejestrowanie czegoś, co pozwoliłoby mojej aplikacji obsłużyć ten protokół. Jeśli to rzeczywiście najlepszy sposób, chciałbym wiedzieć, jak to się robi, ale mam nadzieję, że jest łatwiejszy sposób, aby po prostu powiedzieć: „po kliknięciu linku w tym widoku tekstu chcę zgłosić zdarzenie, które odbiera wartość href linku jako parametr wejściowy „

David Hedlund
źródło
Znalazłem coś innego na [Tutaj] [1] [1]: stackoverflow.com/questions/7255249/ ... Mam nadzieję, że może ci pomóc ^^
Mr_DK
1
David, mam przypadek podobny do twojego, otrzymuję też html z zewnętrznego źródła (sieci), ale jak mam manipulować wartością href w regexie, abym mógł zastosować to rozwiązanie.
X09

Odpowiedzi:

182

Idąc do tego prawie rok później, jest inny sposób, w jaki rozwiązałem mój konkretny problem. Ponieważ chciałem, aby link był obsługiwany przez moją własną aplikację, istnieje rozwiązanie, które jest nieco prostsze.

Oprócz domyślnego filtru intencji, po prostu pozwalam mojej docelowej aktywności słuchać ACTION_VIEWintencji, a konkretnie tych ze schematemcom.package.name

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <action android:name="android.intent.action.VIEW" />
    <data android:scheme="com.package.name" />  
</intent-filter>

Oznacza to, że linki zaczynające się od com.package.name://będą obsługiwane przez moją aktywność.

Wszystko, co muszę zrobić, to stworzyć adres URL zawierający informacje, które chcę przekazać:

com.package.name://action-to-perform/id-that-might-be-needed/

W mojej docelowej aktywności mogę pobrać ten adres:

Uri data = getIntent().getData();

W moim przykładzie mógłbym po prostu sprawdzić datawartości null, ponieważ jeśli kiedykolwiek nie jest to null, będę wiedział, że zostało wywołane za pomocą takiego łącza. Stamtąd wyodrębniam instrukcje, których potrzebuję, z adresu URL, aby móc wyświetlić odpowiednie dane.

David Hedlund
źródło
1
Hej, twoja odpowiedź jest doskonała. Działa dobrze, ale czy dalej możemy przesłać dane przekazanych danych za pomocą tego?
user861973
4
@ user861973: Tak, getDatadaje pełny identyfikator URI, możesz również użyć, getDataStringktóry daje reprezentację tekstową. Tak czy inaczej, możesz skonstruować adres URL tak, aby zawierał wszystkie potrzebne dane com.package.name://my-action/1/2/3/4, i wyodrębnić informacje z tego ciągu.
David Hedlund
3
Zrozumienie tego pomysłu zajęło mi dzień, ale powiem ci co - to było tego warte. Dobrze zaprojektowane rozwiązanie
Dennis
7
świetne rozwiązanie. Nie zapomnij dodać tego do Textview, więc włącza linki. tv.setMovementMethod (LinkMovementMethod.getInstance ());
Daniel Benedykt
3
Przepraszam, ale jaką metodę w ćwiczeniu mam powiedzieć Uri data = getIntent().getData();? Ciągle otrzymuję Activity not found to handle intentbłąd. - Dzięki
rgv
62

Inny sposób, pożycza trochę od Linkify, ale pozwala dostosować obsługę.

Klasa niestandardowej rozpiętości:

public class ClickSpan extends ClickableSpan {

    private OnClickListener mListener;

    public ClickSpan(OnClickListener listener) {
        mListener = listener;
    }

    @Override
    public void onClick(View widget) {
       if (mListener != null) mListener.onClick();
    }

    public interface OnClickListener {
        void onClick();
    }
}

Funkcja pomocnicza:

public static void clickify(TextView view, final String clickableText, 
    final ClickSpan.OnClickListener listener) {

    CharSequence text = view.getText();
    String string = text.toString();
    ClickSpan span = new ClickSpan(listener);

    int start = string.indexOf(clickableText);
    int end = start + clickableText.length();
    if (start == -1) return;

    if (text instanceof Spannable) {
        ((Spannable)text).setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    } else {
        SpannableString s = SpannableString.valueOf(text);
        s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        view.setText(s);
    }

    MovementMethod m = view.getMovementMethod();
    if ((m == null) || !(m instanceof LinkMovementMethod)) {
        view.setMovementMethod(LinkMovementMethod.getInstance());
    }
}

Stosowanie:

 clickify(textView, clickText,new ClickSpan.OnClickListener()
     {
        @Override
        public void onClick() {
            // do something
        }
    });
Jonathan S.
źródło
Innym rozwiązaniem jest zastąpienie zakresów niestandardowymi zakresami, zobacz stackoverflow.com/a/11417498/792677
A-Live,
świetne eleganckie rozwiązanie
Mario Zderic
Uważam, że jest to najprostsze rozwiązanie do wdrożenia. Google nigdy nie uporządkował tego bałaganu, aby konsekwentnie tworzyć klikalne linki w tekstach. To brutalne podejście, aby wymusić na nim rozpiętość, ale działa dobrze w różnych wersjach systemu operacyjnego. +1
angryITguy
55

jeśli w widoku tekstowym jest wiele łączy. Na przykład textview ma „https: //” i „tel no”, możemy dostosować metodę LinkMovement i obsługiwać kliknięcia słów na podstawie wzorca. W załączeniu jest dostosowana metoda przenoszenia łączy.

public class CustomLinkMovementMethod extends LinkMovementMethod
{

private static Context movementContext;

private static CustomLinkMovementMethod linkMovementMethod = new CustomLinkMovementMethod();

public boolean onTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.MotionEvent event)
{
    int action = event.getAction();

    if (action == MotionEvent.ACTION_UP)
    {
        int x = (int) event.getX();
        int y = (int) event.getY();

        x -= widget.getTotalPaddingLeft();
        y -= widget.getTotalPaddingTop();

        x += widget.getScrollX();
        y += widget.getScrollY();

        Layout layout = widget.getLayout();
        int line = layout.getLineForVertical(y);
        int off = layout.getOffsetForHorizontal(line, x);

        URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
        if (link.length != 0)
        {
            String url = link[0].getURL();
            if (url.startsWith("https"))
            {
                Log.d("Link", url);
                Toast.makeText(movementContext, "Link was clicked", Toast.LENGTH_LONG).show();
            } else if (url.startsWith("tel"))
            {
                Log.d("Link", url);
                Toast.makeText(movementContext, "Tel was clicked", Toast.LENGTH_LONG).show();
            } else if (url.startsWith("mailto"))
            {
                Log.d("Link", url);
                Toast.makeText(movementContext, "Mail link was clicked", Toast.LENGTH_LONG).show();
            }
            return true;
        }
    }

    return super.onTouchEvent(widget, buffer, event);
}

public static android.text.method.MovementMethod getInstance(Context c)
{
    movementContext = c;
    return linkMovementMethod;
}

Należy to wywołać z widoku tekstu w następujący sposób:

textViewObject.setMovementMethod(CustomLinkMovementMethod.getInstance(context));
Bieg
źródło
8
Tak naprawdę nie musisz przekazywać kontekstu, więc „za plecami” w oddzielnej zmiennej statycznej, to trochę śmierdzi. Po prostu użyj widget.getContext()zamiast tego.
Sergej Koščejev
Tak, kontekst można usunąć. Dzięki za zwrócenie uwagi Sergej
Arun
6
Działa to znakomicie, ale musisz wywołać setMovementMethod po ustawieniu setText, w przeciwnym razie nadpisze on domyślny LinkMovementMethod
Ray Britton
Działa, ale nie ma potrzeby powtarzania zakresów przy każdym kliknięciu. Również filtrowanie według pozycji wygląda na podatne na błędy. W tej odpowiedzi przedstawiono podobne podejście do jednorazowej inicjalizacji .
Mister Smith
@Arun Zaktualizuj swoją odpowiedź zgodnie z komentarzami.
Behrouz.M
45

Oto bardziej ogólne rozwiązanie oparte na odpowiedzi @Arun

public abstract class TextViewLinkHandler extends LinkMovementMethod {

    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        if (event.getAction() != MotionEvent.ACTION_UP)
            return super.onTouchEvent(widget, buffer, event);

        int x = (int) event.getX();
        int y = (int) event.getY();

        x -= widget.getTotalPaddingLeft();
        y -= widget.getTotalPaddingTop();

        x += widget.getScrollX();
        y += widget.getScrollY();

        Layout layout = widget.getLayout();
        int line = layout.getLineForVertical(y);
        int off = layout.getOffsetForHorizontal(line, x);

        URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
        if (link.length != 0) {
            onLinkClick(link[0].getURL());
        }
        return true;
    }

    abstract public void onLinkClick(String url);
}

Aby z niego skorzystać wystarczy wdrożyć onLinkClickw TextViewLinkHandlerklasie. Na przykład:

    textView.setMovementMethod(new TextViewLinkHandler() {
        @Override
        public void onLinkClick(String url) {
            Toast.makeText(textView.getContext(), url, Toast.LENGTH_SHORT).show();
        }
    });
ruX
źródło
2
działa świetnie. uwaga: nie zapomnij dodać android: autoLink = "web" do swojego widoku tekstu. bez atrybutu autolink to nie działa.
okarakose
Wypróbowałem wszystkie wymienione tutaj rozwiązania. Ten jest dla mnie najlepszy. Jest przejrzysty, prosty w obsłudze i potężny. Wskazówka: aby w pełni wykorzystać możliwości, musisz pracować z Html.fromHtml.
Kai Wang
1
Najlepsza odpowiedź! Dzięki! Nie zapomnij dodać androida: autoLink = "web" w xml lub w kodzie LinkifyCompat.addLinks (textView, Linkify.WEB_URLS);
Nikita Axyonov
1
To, co wydawałoby się prostym wymaganiem, jest dość złożoną sprawą w systemie Android. To rozwiązanie usuwa wiele bólu. Okazało się, że funkcja autoLink = "web" nie jest wymagana, aby to rozwiązanie działało na Androidzie N .. +1
angryITguy
1
Dlaczego na świecie taka klasa nie istnieje natywnie - po tylu latach - jest poza mną. Dzięki Androidowi za LinkMovementMethod, ale zazwyczaj chciałbym mieć kontrolę nad własnym interfejsem użytkownika. Możesz zgłaszać mi zdarzenia interfejsu użytkownika, aby MÓJ kontroler mógł je obsłużyć.
podpis metodologiczny
10

to bardzo proste, dodaj tę linię do swojego kodu:

tv.setMovementMethod(LinkMovementMethod.getInstance());
Jonathan
źródło
1
Dzięki za odpowiedź, Jonathan. Tak, wiedziałem o MovementMethod; nie byłem pewien, jak określić, że moja własna aplikacja powinna obsługiwać kliknięcie linku, a nie tylko otwierać przeglądarkę, jak to zrobiłaby domyślna metoda ruchu (zobacz zaakceptowaną odpowiedź). W każdym razie dzięki.
David Hedlund
5

Rozwiązanie

Zaimplementowałem małą klasę, za pomocą której można obsługiwać długie kliknięcia samego TextView i kliknięć w linki w TextView.

Układ

TextView android:id="@+id/text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:autoLink="all"/>

TextViewClickMovement.java

import android.content.Context;
import android.text.Layout;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Patterns;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.TextView;

public class TextViewClickMovement extends LinkMovementMethod {

    private final String TAG = TextViewClickMovement.class.getSimpleName();

    private final OnTextViewClickMovementListener mListener;
    private final GestureDetector                 mGestureDetector;
    private TextView                              mWidget;
    private Spannable                             mBuffer;

    public enum LinkType {

        /** Indicates that phone link was clicked */
        PHONE,

        /** Identifies that URL was clicked */
        WEB_URL,

        /** Identifies that Email Address was clicked */
        EMAIL_ADDRESS,

        /** Indicates that none of above mentioned were clicked */
        NONE
    }

    /**
     * Interface used to handle Long clicks on the {@link TextView} and taps
     * on the phone, web, mail links inside of {@link TextView}.
     */
    public interface OnTextViewClickMovementListener {

        /**
         * This method will be invoked when user press and hold
         * finger on the {@link TextView}
         *
         * @param linkText Text which contains link on which user presses.
         * @param linkType Type of the link can be one of {@link LinkType} enumeration
         */
        void onLinkClicked(final String linkText, final LinkType linkType);

        /**
         *
         * @param text Whole text of {@link TextView}
         */
        void onLongClick(final String text);
    }


    public TextViewClickMovement(final OnTextViewClickMovementListener listener, final Context context) {
        mListener        = listener;
        mGestureDetector = new GestureDetector(context, new SimpleOnGestureListener());
    }

    @Override
    public boolean onTouchEvent(final TextView widget, final Spannable buffer, final MotionEvent event) {

        mWidget = widget;
        mBuffer = buffer;
        mGestureDetector.onTouchEvent(event);

        return false;
    }

    /**
     * Detects various gestures and events.
     * Notify users when a particular motion event has occurred.
     */
    class SimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onDown(MotionEvent event) {
            // Notified when a tap occurs.
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            // Notified when a long press occurs.
            final String text = mBuffer.toString();

            if (mListener != null) {
                Log.d(TAG, "----> Long Click Occurs on TextView with ID: " + mWidget.getId() + "\n" +
                                  "Text: " + text + "\n<----");

                mListener.onLongClick(text);
            }
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent event) {
            // Notified when tap occurs.
            final String linkText = getLinkText(mWidget, mBuffer, event);

            LinkType linkType = LinkType.NONE;

            if (Patterns.PHONE.matcher(linkText).matches()) {
                linkType = LinkType.PHONE;
            }
            else if (Patterns.WEB_URL.matcher(linkText).matches()) {
                linkType = LinkType.WEB_URL;
            }
            else if (Patterns.EMAIL_ADDRESS.matcher(linkText).matches()) {
                linkType = LinkType.EMAIL_ADDRESS;
            }

            if (mListener != null) {
                Log.d(TAG, "----> Tap Occurs on TextView with ID: " + mWidget.getId() + "\n" +
                                  "Link Text: " + linkText + "\n" +
                                  "Link Type: " + linkType + "\n<----");

                mListener.onLinkClicked(linkText, linkType);
            }

            return false;
        }

        private String getLinkText(final TextView widget, final Spannable buffer, final MotionEvent event) {

            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

            if (link.length != 0) {
                return buffer.subSequence(buffer.getSpanStart(link[0]),
                        buffer.getSpanEnd(link[0])).toString();
            }

            return "";
        }
    }
}

Stosowanie

TextView tv = (TextView) v.findViewById(R.id.textview);
tv.setText(Html.fromHtml("<a href='test'>test</a>"));
textView.setMovementMethod(new TextViewClickMovement(this, context));

Spinki do mankietów

Mam nadzieję że to pomoże! Możesz znaleźć kod tutaj .

Victor Apoyan
źródło
3

Tylko po to, aby udostępnić alternatywne rozwiązanie za pomocą utworzonej przeze mnie biblioteki. Dzięki Textoo można to osiągnąć na przykład:

TextView locNotFound = Textoo
    .config((TextView) findViewById(R.id.view_location_disabled))
    .addLinksHandler(new LinksHandler() {
        @Override
        public boolean onClick(View view, String url) {
            if ("internal://settings/location".equals(url)) {
                Intent locSettings = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(locSettings);
                return true;
            } else {
                return false;
            }
        }
    })
    .apply();

Lub z dynamicznym źródłem HTML:

String htmlSource = "Links: <a href='http://www.google.com'>Google</a>";
Spanned linksLoggingText = Textoo
    .config(htmlSource)
    .parseHtml()
    .addLinksHandler(new LinksHandler() {
        @Override
        public boolean onClick(View view, String url) {
            Log.i("MyActivity", "Linking to google...");
            return false; // event not handled.  Continue default processing i.e. link to google
        }
    })
    .apply();
textView.setText(linksLoggingText);
PH88
źródło
To powinna być najlepsza odpowiedź. Dziękuję panu za wkład
Marian Pavel
3

kto szuka tutaj więcej opcji, jest jednym

// Set text within a `TextView`
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("Hey @sarah, where did @jim go? #lost");
// Style clickable spans based on pattern
new PatternEditableBuilder().
    addPattern(Pattern.compile("\\@(\\w+)"), Color.BLUE,
       new PatternEditableBuilder.SpannableClickedListener() {
        @Override
        public void onSpanClicked(String text) {
            Toast.makeText(MainActivity.this, "Clicked username: " + text,
                Toast.LENGTH_SHORT).show();
        }
}).into(textView);

ZASOBY: CodePath

Dasser Basyouni
źródło
2
public static void setTextViewFromHtmlWithLinkClickable(TextView textView, String text) {
    Spanned result;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        result = Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
    } else {
        result = Html.fromHtml(text);
    }
    textView.setText(result);
    textView.setMovementMethod(LinkMovementMethod.getInstance());
}
Kai Wang
źródło
1

Zmieniłem kolor TextView na niebieski, używając na przykład:

android:textColor="#3399FF"

w pliku xml. Jak go podkreślić, wyjaśniono tutaj .

Następnie użyj jego właściwości onClick, aby określić metodę (domyślam się, że możesz zadzwonić setOnClickListener(this)w inny sposób), np:

myTextView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
    doSomething();
}
});

Dzięki tej metodzie mogę normalnie robić, co chcę, na przykład uruchomić intencję. Zauważ, że nadal musisz wykonać normalną myTextView.setMovementMethod(LinkMovementMethod.getInstance());czynność, na przykład w metodzie onCreate () Twojej aktywności.

Tyler Collier
źródło
1

Ta odpowiedź rozszerza doskonałe rozwiązanie Jonathana S.

Możesz użyć następującej metody, aby wyodrębnić linki z tekstu:

private static ArrayList<String> getLinksFromText(String text) {
        ArrayList links = new ArrayList();

        String regex = "\(?\b((http|https)://www[.])[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(text);
        while (m.find()) {
            String urlStr = m.group();
            if (urlStr.startsWith("(") && urlStr.endsWith(")")) {
                urlStr = urlStr.substring(1, urlStr.length() - 1);
            }
            links.add(urlStr);
        }
        return links;
    }

Można to wykorzystać do usunięcia jednego z parametrów w clickify()metodzie:

public static void clickify(TextView view,
                                final ClickSpan.OnClickListener listener) {

        CharSequence text = view.getText();
        String string = text.toString();


        ArrayList<String> linksInText = getLinksFromText(string);
        if (linksInText.isEmpty()){
            return;
        }


        String clickableText = linksInText.get(0);
        ClickSpan span = new ClickSpan(listener,clickableText);

        int start = string.indexOf(clickableText);
        int end = start + clickableText.length();
        if (start == -1) return;

        if (text instanceof Spannable) {
            ((Spannable) text).setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            SpannableString s = SpannableString.valueOf(text);
            s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            view.setText(s);
        }

        MovementMethod m = view.getMovementMethod();
        if ((m == null) || !(m instanceof LinkMovementMethod)) {
            view.setMovementMethod(LinkMovementMethod.getInstance());
        }
    }

Kilka zmian w ClickSpan:

public static class ClickSpan extends ClickableSpan {

        private String mClickableText;
        private OnClickListener mListener;

        public ClickSpan(OnClickListener listener, String clickableText) {
            mListener = listener;
            mClickableText = clickableText;
        }

        @Override
        public void onClick(View widget) {
            if (mListener != null) mListener.onClick(mClickableText);
        }

        public interface OnClickListener {
            void onClick(String clickableText);
        }
    }

Teraz możesz po prostu ustawić tekst w TextView, a następnie dodać do niego detektor:

TextViewUtils.clickify(textWithLink,new TextUtils.ClickSpan.OnClickListener(){

@Override
public void onClick(String clickableText){
  //action...
}

});
WKS
źródło
0

Najlepszy sposób, w jaki korzystałem i zawsze działał

android:autoLink="web"
Rohit Mandiwal
źródło
8
To wcale nie odpowiada na pytanie.
Tom
0

Przykład: załóżmy, że ustawiłeś tekst w widoku tekstu i chcesz podać link do określonego wyrażenia tekstowego: „Kliknij #facebook przeniesie Cię na facebook.com”

W układzie XML:

<TextView
            android:id="@+id/testtext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

W aktywności:

String text  =  "Click on #facebook will take you to facebook.com";
tv.setText(text);
Pattern tagMatcher = Pattern.compile("[#]+[A-Za-z0-9-_]+\\b");
String newActivityURL = "content://ankit.testactivity/";
Linkify.addLinks(tv, tagMatcher, newActivityURL);

Utwórz również jednego dostawcę tagów jako:

public class TagProvider extends ContentProvider {

    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public String getType(Uri arg0) {
        return "vnd.android.cursor.item/vnd.cc.tag";
    }

    @Override
    public Uri insert(Uri arg0, ContentValues arg1) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
                        String arg4) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
        // TODO Auto-generated method stub
        return 0;
    }

}

W pliku manifestu wprowadź dane dla dostawcy i testuj jako:

<provider
    android:name="ankit.TagProvider"
    android:authorities="ankit.testactivity" />

<activity android:name=".TestActivity"
    android:label = "@string/app_name">
    <intent-filter >
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.item/vnd.cc.tag" />
    </intent-filter>
</activity>

Teraz po kliknięciu #facebook wywoła testactivtiy. W aktywności testowej możesz uzyskać dane jako:

Uri uri = getIntent().getData();
Ankit Adlakha
źródło