422

Can anybody please guide me regarding how to launch my android application from the android browser?

Rahul Tiwari
  • 5,931
  • 2
  • 41
  • 66
Parimal Modi
  • 4,229
  • 3
  • 13
  • 3

16 Answers16

628

Use an <intent-filter> with a <data> element. For example, to handle all links to twitter.com, you'd put this inside your <activity> in your AndroidManifest.xml:

<intent-filter>
    <data android:scheme="http" android:host="twitter.com"/>
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

Then, when the user clicks on a link to twitter in the browser, they will be asked what application to use in order to complete the action: the browser or your application.

Of course, if you want to provide tight integration between your website and your app, you can define your own scheme:

<intent-filter>
    <data android:scheme="my.special.scheme" />
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

Then, in your web app you can put links like:

<a href="my.special.scheme://other/parameters/here">

And when the user clicks it, your app will be launched automatically (because it will probably be the only one that can handle my.special.scheme:// type of uris). The only downside to this is that if the user doesn't have the app installed, they'll get a nasty error. And I'm not sure there's any way to check.


Edit: To answer your question, you can use getIntent().getData() which returns a Uri object. You can then use Uri.* methods to extract the data you need. For example, let's say the user clicked on a link to http://twitter.com/status/1234:

Uri data = getIntent().getData();
String scheme = data.getScheme(); // "http"
String host = data.getHost(); // "twitter.com"
List<String> params = data.getPathSegments();
String first = params.get(0); // "status"
String second = params.get(1); // "1234"

You can do the above anywhere in your Activity, but you're probably going to want to do it in onCreate(). You can also use params.size() to get the number of path segments in the Uri. Look to javadoc or the android developer website for other Uri methods you can use to extract specific parts.

Felix
  • 84,032
  • 41
  • 145
  • 163
  • 6
    Thanks a ton for your prompt reply. But can you please tell me how to access the parameters after "my.special.scheme://". – Parimal Modi Jun 02 '10 at 15:46
  • 4
    I've edited my answer to include instructions on how to extract the data from the Uri. Please mark this answer as accepted (only) if you consider it so by clicking the checkmark next to it. – Felix Jun 02 '10 at 19:58
  • i had a similar question, then found your answer it is perfect. I have one downside, if i open the app without clicking a link ... nullpointerexception ... so i tried to make a check if the data is null then don't try to fetch data but that doesn't work either. Any idea how to solve this minor problem? – Johan Aug 13 '10 at 12:50
  • 1
    this is one of the most useful answers on SO about android webviews – SaKet Aug 24 '11 at 21:04
  • is that really better to put it in onCreate than in onResume OR in onNewIntent when the activity uses the singleTop launchMode ? – Alexis Sep 11 '12 at 11:52
  • 9
    what if the targeted android application is not installed? How to handle this. – Nemo Sep 14 '12 at 07:24
  • how can I apply this to a mobile hybrid app built on html5, css3 and javascript only which I use web marmalade to compile? There is no manifest file for this approach. – Unomono Feb 06 '13 at 08:32
  • Would it be possible to intercept the posted data and not only the URL? – Mister Smith Apr 19 '13 at 09:21
  • 1
    @MisterSmith no, that is HTTP-specific. **But**, you can add data to your url, as GET parameters. – Felix Apr 19 '13 at 11:38
  • @Felix - How do you parse parameters if passed with the uri - such as www.blablabal.com/mycode.aspx?gameid=1232323 ? Thanks... – Dani Jan 25 '14 at 16:26
  • @Dani check out [getIntent()](https://developer.android.com/reference/android/app/Activity.html#getIntent()), [getData()](https://developer.android.com/reference/android/content/Intent.html#getData()) and the [Uri object](https://developer.android.com/reference/android/net/Uri.html). – Felix Jan 26 '14 at 15:10
  • 13
    Anyone who, like me, is unable to get this scheme work, needs to add `android:exported="true"` to their `Activity` in manifest. Check this answer http://stackoverflow.com/a/13044911/1276636 – Sufian Aug 27 '14 at 06:19
  • Hi, I know this post is too old, but can you guide on how to achieve this in phonegap? – fiberOptics Oct 21 '14 at 14:26
  • 5
    Not sure how this is working for the entire world. Just doesn't work on chrome and it always opens the link in browser until you place the "android:pathPrefix" element. The answer anyways doesn't have the category values as mentioned in the documentation. If it still doesn't work for someone, refer this please: http://stackoverflow.com/a/21727055/2695276 PS: struggled for days over this. – Rajat Sharma Jan 02 '15 at 21:06
  • I dont know its working on all the devices but not on Android Lollipop. Please help – Ahmad Arslan Apr 14 '15 at 06:42
  • @Felix this does not works on android lollipop until your scheme is http or https... and if it is so, it launches the default app(browser) and shows nothing, my app never runs :/ – Salmaan Apr 14 '15 at 09:46
  • 1
    It should be noted that functionality changed since Chrome version 25. Refer to [this page](https://developer.chrome.com/multidevice/android/intents) for details about the new approach. – BaCaRoZzo May 24 '15 at 13:38
  • @Felix i have similar issue http://stackoverflow.com/questions/35716173/how-to-open-application-on-click-of-confrimation-link – Aditya Vyas-Lakhan Mar 01 '16 at 06:47
  • Note that there is now an in-built editor available for Android Studio https://developer.android.com/studio/write/app-link-indexing.html – Dani Dec 03 '17 at 15:12
  • @Felix In click of URL i am get the JSON object in which i will get (MyApp://?screen=upgrade) so in manifest file i have to write only plz help me out – Atul Dhanuka Jan 22 '18 at 06:04
  • @Felix sorry for above comment just want to ask In click of URL server will redirect me to these URL (MyApp://?screen=upgrade) so in manifest file i have to write only plz help me out – Atul Dhanuka Jan 22 '18 at 06:24
  • host not important, so you can dont set it. – roghayeh hosseini Oct 11 '20 at 20:36
72

All above answers didn't work for me with CHROME as of 28 Jan 2014

my App launched properly from http://example.com/someresource/ links from apps like hangouts, gmail etc but not from within chrome browser.

to solve this, so that it launches properly from CHROME you have to set intent filter like this

<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:host="example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
    <data
        android:host="www.example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
</intent-filter>

note the pathPrefix element

your app will now appear inside activity picker whenever user requests http://example.com/someresource/ pattern from chrome browser by clicking a link from google search results or any other website

aldok
  • 13,524
  • 4
  • 47
  • 61
AndroidGecko
  • 13,296
  • 3
  • 31
  • 47
  • This helped me so much. Thanks a lot! Please post your answer here so I can award you the bounty! http://stackoverflow.com/questions/21663001/launching-custom-android-application-from-android-browser-chrome – Vlad Schnakovszki Feb 12 '14 at 11:38
  • What language is this? – Dims Apr 07 '14 at 16:00
  • Hello, I know its too old. I am also struck in same scenario. I have specified pathPrefix, scheme and host but its not working. I tried with scheme only, then it worked. But when I added host, it stopped working. Any idea what can be the issue? – seema Aug 25 '14 at 12:47
  • Spent days over it until I came to this answer. Not sure how it worked for the entire world without the pathPrefix element. Never worked for me on chrome despite doing everything as per the documentation. Thank you so much. – Rajat Sharma Jan 02 '15 at 21:13
67

Please see my comment here: Make a link in the Android browser start up my app?

We strongly discourage people from using their own schemes, unless they are defining a new world-wide internet scheme.

Community
  • 1
  • 1
hackbod
  • 88,517
  • 16
  • 135
  • 152
  • 10
    Hackbod is one of the Google engineers behind the Android platform. It's probably a good idea to follow this advice. In fact, it seems like custom scheme support like this broke in Honeycomb. – nmr Oct 03 '11 at 22:18
  • 2
    I believe that you have to make your own scheme if you want the URL to also work on iPhone (e.g., from a QR code). – Lawrence Kesteloot May 15 '12 at 21:46
  • 23
    I can't be held responsible for limitations imposed on developers by iOS. ;) – hackbod May 15 '12 at 22:48
  • 12
    held responsible? no. But you could take it into account since, regardless of if you like it or not, those limitations are imposed on many of your developers – ByteMe Jul 16 '12 at 23:56
  • 6
    hackbod is answering a question specifically for Android. There's no mention of iOS, so no need to take it into account. – nilskp Jul 29 '12 at 20:56
  • 4
    @hackbod would namespacing a scheme (i.e. href="com.ourdomain.myapp//whatever") a good practice, supposing that a link like that could be found on different websites? – Julien Bérubé Sep 18 '12 at 14:57
48

In my case I had to set two categories for the <intent-filter> and then it worked:

<intent-filter>
<data android:scheme="my.special.scheme" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
Zaki
  • 481
  • 4
  • 3
27

For example, You have next things:

A link to open your app: http://example.com

The package name of your app: com.example.mypackage

Then you need to do next:

  1. Add an intent filter to your Activity (Can be any activity you want. For more info check the documentation).

    <activity
         android:name=".MainActivity">
    
         <intent-filter android:label="@string/filter_title_view_app_from_web">
             <action android:name="android.intent.action.VIEW" />
             <category android:name="android.intent.category.DEFAULT" />
             <category android:name="android.intent.category.BROWSABLE" />
             <!-- Accepts URIs that begin with "http://example.com" -->
    
             <data
                 android:host="example.com"
                 android:scheme="http" />
         </intent-filter>
    
         <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
    
     </activity> 
    
  2. Create a HTML file to test the link or use this methods.

    Open your Activity directly (just open your Activity, without a choosing dialog).

    Open this link with browser or your programm (by choosing dialog).

  3. Use Mobile Chrome to test

  4. That's it.

And its not necessary to publish app in market to test deep linking =)

Also, for more information, check documentation and useful presentation.

AbolfazlR
  • 4,786
  • 3
  • 30
  • 50
Denshov
  • 1,369
  • 1
  • 16
  • 29
18

There should also be <category android:name="android.intent.category.BROWSABLE"/> added to the intent filter to make the activity recognized properly from the link.

georgij
  • 1,690
  • 2
  • 22
  • 36
  • 4
    For reference, adding CATEGORY_BROWSABLE means that "The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message." – greg7gkb Jul 09 '12 at 18:39
  • Is this an existing category or are you proposing a new one? – Anish Aug 13 '12 at 21:14
  • It exists. Apparently you should have separate website host in different intent-filter tags, or it causes problems. – NoBugs Oct 13 '12 at 20:58
  • 2
    Not just BROWSABLE, but also android.intent.category.DEFAULT - so the link could be opened when initiated in other apps, like email (not just browsers) – AlikElzin-kilaka Dec 30 '13 at 11:38
8

The following link gives information on launching the app (if installed) directly from browser. Otherwise it directly opens up the app in play store so that user can seamlessly download.

https://developer.chrome.com/multidevice/android/intents

Varun Bhatia
  • 4,086
  • 29
  • 38
7

Please note if your icon is disappear from android launcher when you implement this feature, than you have to split intent-filter.

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <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="your-own-uri" />
        </intent-filter>
    </activity>
Zoltan
  • 4,800
  • 1
  • 33
  • 39
6

Yeah, Chrome searches instead of looking for scheme. If you want to launch your App through URI scheme, use this cool utility App on the Play store. It saved my day :) https://play.google.com/store/apps/details?id=com.naosim.urlschemesender

RRK
  • 365
  • 3
  • 7
6

Xamarin port of Felix's answer

In your MainActivity, add this (docs: Android.App.IntentFilterAttribute Class):

....
[IntentFilter(new[] { 
    Intent.ActionView }, 
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, 
    DataScheme = "my.special.scheme")
]
public class MainActivity : Activity
{
    ....

Xamarin will add following in the AndroidManifest.xml for you:

<activity
    android:label="Something"
    android:screenOrientation="portrait"
    android:theme="@style/MyTheme"
    android:name="blah.MainActivity">
    <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="my.special.scheme" />
    </intent-filter>
</activity>

And in order to get params (I tested in OnCreate of MainActivity):

var data = Intent.Data;
if (data != null)
{
    var scheme = data.Scheme;
    var host = data.Host;
    var args = data.PathSegments;

    if (args.Count > 0)
    {
        var first = args[0];
        var second = args[1];
        ...
    }
}

As far as I know, above can be added in any activity, not only MainActivity

Notes:

  1. When user click on the link, Android OS relaunch your app (kill prev instance, if any, and run new one), means the OnCreate event of app's MainLauncher Activity will be fired again.
  2. With this link: <a href="my.special.scheme://host/arg1/arg2">, in above last code snippet values will be:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

Update: if android creates new instance of your app, you should add android:launchMode="singleTask" too.

Mehdi Dehghani
  • 8,186
  • 5
  • 49
  • 53
3

Felix's approach to handling deep links is the typical approach to handling deep links. I would also suggest checking out this library to handle the routing and parsing of your deep links:

https://github.com/airbnb/DeepLinkDispatch

You can use annotations to register your Activity for a particular deep link URI, and it will extract out the parameters for you without having to do the usual rigmarole of getting the path segments, matching it, etc. You could simply annotate and activity like this:

@DeepLink("somePath/{someParameter1}/{someParameter2}")
public class MainActivity extends Activity {
   ...
}
Christian
  • 729
  • 7
  • 14
0

example.php:

<?php
if(!isset($_GET['app_link'])){  ?>   
    <iframe src="example.php?app_link=YourApp://blabla" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <iframe src="example.php?full_link=http://play.google.com/xyz" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <?php 
}
else { ?>
    <script type="text/javascript">
    self.window.location        = '<?php echo $_GET['app_link'];?>';
    window.parent.location.href = '<?php echo $_GET['full_link'];?>';
    </script>
<?php 
}
T.Todua
  • 44,747
  • 17
  • 195
  • 185
  • 1
    This creates two invisible iframes: deep link and normal link. If the app is installed, the deep link iframe will launch it. If not, the normal link is displayed. With some extra work, deferred deep linking could be implemented where the deep link is called after the app is installed. – Dominic Cerisano Dec 03 '17 at 07:13
0

Hey I got the solution. I did not set the category as "Default". Also I was using the Main activity for the intent Data. Now i am using a different activity for the intent data. Thanks for the help. :)

Parimal Modi
  • 21
  • 1
  • 3
  • Sounds unlikely (although I recognize that this is an old question and maybe things have changed.) From http://developer.android.com/guide/components/intents-filters.html#ifs "For an intent to pass the category test, every category in the Intent *object* must match a category in the *filter*. The filter can list additional categories, but it cannot omit any that are in the intent." – Noach Magedman Apr 18 '13 at 15:21
0

You need to add a pseudo-hostname to the CALLBACK_URL 'app://' doesn't make sense as a URL and cannot be parsed.

Paul Lindner
  • 1,450
  • 9
  • 6
0

Look @JRuns answer in here. The idea is to create html with your custom scheme and upload it somewhere. Then if you click on your custom link on your html-file, you will be redirected to your app. I used this article for android. But dont forget to set full name Name = "MyApp.Mobile.Droid.MainActivity" attribute to your target activity.

S. Koshelnyk
  • 412
  • 1
  • 3
  • 16
0

As of 15/06/2019

what I did is include all four possibilities to open url.

i.e, with http / https and 2 with www in prefix and 2 without www

and by using this my app launches automatically now without asking me to choose a browser and other option.

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https" android:host="example.in" />
    <data android:scheme="https" android:host="www.example.in" />
    <data android:scheme="http" android:host="example.in" />
    <data android:scheme="http" android:host="www.example.in" />

</intent-filter>
Vicky Salunkhe
  • 4,955
  • 2
  • 30
  • 42