110

I'd like to be able to prompt my app to open a link when user clicks on an URL of a given pattern instead of allowing the browser to open it. This could be when the user is on a web page in the browser or in an email client or within a WebView in a freshly-minted app.

For example, click on a YouTube link from anywhere in the phone and you'll be given the chance to open the YouTube app.

How do I achieve this for my own app?

Artiom
  • 7,694
  • 3
  • 38
  • 45
jamesh
  • 19,863
  • 14
  • 56
  • 96

3 Answers3

142

Use an android.intent.action.VIEW of category android.intent.category.BROWSABLE.

From Romain Guy's Photostream app's AndroidManifest.xml,

    <activity
        android:name=".PhotostreamActivity"
        android:label="@string/application_name">

        <!-- ... -->            

        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="http"
                  android:host="flickr.com"
                  android:pathPrefix="/photos/" />
            <data android:scheme="http"
                  android:host="www.flickr.com"
                  android:pathPrefix="/photos/" />
        </intent-filter>
    </activity>

Once inside you're in the activity, you need to look for the action, and then do something with the URL you've been handed. The Intent.getData() method gives you a Uri.

    final Intent intent = getIntent();
    final String action = intent.getAction();

    if (Intent.ACTION_VIEW.equals(action)) {
        final List<String> segments = intent.getData().getPathSegments();
        if (segments.size() > 1) {
            mUsername = segments.get(1);
        }
    }

It should be noted, however, that this app is getting a little bit out of date (1.2), so you may find there are better ways of achieving this.

jamesh
  • 19,863
  • 14
  • 56
  • 96
  • 9
    One thing to be aware of - your user will be presented with choice of using the suitable app since all you do is to register yours app as a handler. Personally (as user) I'm annoyed with that though I realize that I can opt for "default action" – Bostone Oct 22 '09 at 22:25
  • 1
    This does not work for HTC Phones. How can I make it work on HTC phones? – user484691 Sep 18 '12 at 18:39
  • 59
    You will probably want to use intent.getDataString() rather than getData() if you care about the full URL including the querystring. This comment will save you the hour it just cost me..... :-( – Kenton Price Oct 30 '12 at 13:26
  • 1
    Will this be called for every URL the user navigates to from any app or just the native browser? – gonzobrains Apr 30 '13 at 23:04
  • 2
    From any app (that uses the Intent.ACTION_VIEW intent) – jamesh Jun 10 '13 at 12:17
  • Can you please guide me what happens when user have selected the default app as chrome or firefox? – Salmaan Feb 10 '15 at 05:03
  • segments.size() should check for greater then zero – Amit Tumkur May 06 '16 at 06:30
  • Does this work for relative URL's as well. Because my website has relative URL's and it doesn't work. http://stackoverflow.com/questions/38701483/app-links-in-chrome-dont-open-app-when-clicked – Akshay Goyal Aug 03 '16 at 11:06
  • Can you explain the usage of `mUsername ` ? – Yash Karanke Feb 08 '18 at 13:06
3

There are some libraries parse parameters from url automatically.

such as

https://github.com/airbnb/DeepLinkDispatch

&&

https://github.com/mzule/ActivityRouter

The later one is wrote by me. Which can parse parameters to given type, not always String.

Example

@Router(value = "main/:id" intExtra = "id")
...
int id = getIntent().getInt("id", 0);
Cao Dongping
  • 969
  • 1
  • 12
  • 29
1
private class MyWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        setUrlparams(url);

        if (url.indexOf("pattern") != -1) {
            // do something
            return false;
        } else {
            view.loadUrl(url);
        }

        return true;
    }

}
Dacx
  • 43
  • 1
  • 4
    Thanks. This is useful in the context where you own the webview. The question I was asking was how do I get my app to intercept a click on a link in any app (e.g. the browser). – jamesh Jan 17 '10 at 01:21