Make a link in the Android browser start up my app?
Asked Answered
T

10

247

Is it possible to make a link such as:

<a href="anton://useful_info_for_anton_app">click me!</a>

cause my Anton app to start up?

I know that this works for the Android Market app with the market protocol, but can something similar be done with other apps?

Here is an example of a link that will start up the Android Market:

<a href="market://search?q=pname:com.nytimes.android">click me!</a>

Update: The answer I accepted provided by eldarerathis works great, but I just want to mention that I had some trouble with the order of the subelements of the <intent-filter> tag. I suggest you simply make another <intent-filter> with the new subelements in that tag to avoid the problems I had. For instance my AndroidManifest.xml looks like this:

<activity android:name=".AntonWorld"
          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>
        <data android:scheme="anton" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
Tropic answered 12/8, 2010 at 16:33 Comment(7)
This solved my problem when I cannot open the application in my mobile.Zilber
+1 for mentioning the ordering of the xml tags. It makes absolutely no sense and isn't documented anywhere, but I found that when I had the data tag below the action and category tags, it would just plain not work.Tantra
Redirecting to the app and correctly falling back if the app is not present can be a bit of a nightmare too, given the complexities of all the different Android browsers (Chrome, Default, Webviews, Firefox, etc). The branch.io service helps do this and is free.Claudy
@Tropic ....hello sir...by yours above code, i only understand to handle the data from the link...Can you please tell me that how can i create a link which contains my data...please help me...I want to create the link with data on button click event..Ombudsman
Possible duplicate of Launch custom android application from android browserSquib
⚠️I tripped across a debugging hurdle that others may want to be aware of as well: The links work from <a href=""> links in web pages and when launched with adb, but now when you just type the URL in the mobile browser address bar.⚠️Isobath
can we app linking on page load ? without user interaction?Ruthenic
P
101

I think you'll want to look at the <intent-filter> element of your Manifest file. Specifically, take a look at the documentation for the <data> sub-element.

Basically, what you'll need to do is define your own scheme. Something along the lines of:

<intent-filter>
    <data android:scheme="anton" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" /> <--Not positive if this one is needed
    ...
</intent-filter>

Then you should be able to launch your app with links that begin with the anton: URI scheme.

Paternoster answered 12/8, 2010 at 16:44 Comment(14)
That works great! Do you have any idea how to grab the "useful_info_for_anton_app" once my application is launched from the link?Tropic
Try taking a look at this thread. It has a pretty good example: #2959201Paternoster
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."Mink
Please follow the link which eldarerathis has suggested.It is really helpful.Roomer
The ORDER! As noted in a comment above, the order of the elements is significant and finally worked for me when ordered like this answer.Immure
Ok and if someone knows how to launch an app in separate sandbox? When I launch my app from browser in starts on top of the browser. I need something like launchig apps from Play Market on Open button click, but with url linksReflective
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: https://mcmap.net/q/81883/-launching-custom-android-application-from-android-browser-chrome PS: struggled for days over this.Demoralize
This works perfectly on previous android versions, but not on lollipop, any solution?Rozellarozelle
@Paternoster this works if application is close but if application is running on the background and the activity is different than the one which intent filter attached I could not handle it. How do you manage this to work for in all activities? Do you put intent filter into all of them?Afield
@Paternoster ....hello sir...by yours above code, i only understand to handle the data from the link...Can you please tell me that how can i create a link which contains my data...please help me...I want to create the link with data on button click event..Ombudsman
This answer is outdated..this will not work post chrome 40. The custom scheme has been disabled in chrome due to security issuesBeacon
@Paternoster This is not working for me, you can see my question. #54748713Sidoney
can we app link in android from java script in background, without user interaction?Ruthenic
how to get data which is in the url after launching app using this?Bakelite
H
287

Please DO NOT use your own custom scheme like that!!! URI schemes are a network global namespace. Do you own the "anton:" scheme world-wide? No? Then DON'T use it.

One option is to have a web site, and have an intent-filter for a particular URI on that web site. For example, this is what Market does to intercept URIs on its web site:

        <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="market.android.com"
                android:path="/search" />
        </intent-filter>

Alternatively, there is the "intent:" scheme. This allows you to describe nearly any Intent as a URI, which the browser will try to launch when clicked. To build such a scheme, the best way is to just write the code to construct the Intent you want launched, and then print the result of intent.toUri(Intent.URI_INTENT_SCHEME).

You can use an action with this intent for to find any activity supporting that action. The browser will automatically add the BROWSABLE category to the intent before launching it, for security reasons; it also will strip any explicit component you have supplied for the same reason.

The best way to use this, if you want to ensure it launches only your app, is with your own scoped action and using Intent.setPackage() to say the Intent will only match your app package.

Trade-offs between the two:

  • http URIs require you have a domain you own. The user will always get the option to show the URI in the browser. It has very nice fall-back properties where if your app is not installed, they will simply land on your web site.

  • intent URIs require that your app already be installed and only on Android phones. The allow nearly any intent (but always have the BROWSABLE category included and not supporting explicit components). They allow you to direct the launch to only your app without the user having the option of instead going to the browser or any other app.

Hyo answered 12/8, 2010 at 21:32 Comment(23)
Hey @hackbod! I did some investigation on this, please see my question here: #3564893 Looks like the GMail client messes up the Intent URI. :(Peripeteia
On the other hand, the Market app also handles market:// links :)Dichogamy
It was a mistake for it to use market:, and this is being removed.Hyo
The reason why people use custom schemes in Android is because most of project are developed in paralel with (or after) the iPhone version, and this is the only way to make it work there...Lumumba
agree with @LambergaR. Now we need to find out a way to make a link in an email work in 3 platforms (BB, iphone, Android)Beadledom
Any URI you put in your web page with a custom scheme will not work on any web browser that doesn't have also your application installed. Doesn't that seem broken to you?Hyo
You may claim Google is trying to move away from this, and yet they still define their own scheme for their Authenticator app. It registers the otpauth scheme.Sienna
@Hyo Here you say custom URL schemes are bad, but here other Googles advise their use: docs.google.com/document/d/… Shouldn't they be recommending intent URLs specifying the app package? It doesn't seem secure at all to use only a custom scheme.Unanimity
yep, and what about the itunes scheme ?Girosol
Please see code.google.com/p/android/issues/detail?id=22971 Where this behavior is broken on ICS. It seems custom scheme is the most reliable way to go for different Android versions and browsers.Isolde
Not a portable solution. I don't prefer a solution that works only Android's stock browser, and doesn't work in Chrome, Firefox etc. I don't prefer to handle my callbacks regarding to OS (iOs or Android)Wiredraw
@Hyo Is there any way for the browser to launch a new instance of the app (or switch the active process to the existing app) instead of opening within the browser app? I have noticed that some apps have this functionality (Gmail can launch Chrome, Play can launch any app), and I was wondering if it is supported by this intents/URIs method.Tamikatamiko
@Tamikatamiko yes it is possible to open the active app from a browser. Set your main activity android:launchMode="singleTask" in your AndroidManifest.xml. This has worked for me. And as for the rest of the debate going on, until there is a better solution I'm still going to use my own scheme. Supporting android and iOS this is a good solution.Debouchment
How to test this in dev mode? I have custom URL with http scheme and path. I have provided intent filter in my manifest and created a separate activity for this intent filter. However, if I click on mobile site link, my app doesn't automatically start. Any help will be appreciated.Fault
@Hyo That's a great answer. Just wondering whether the same would work from within the SMS too? I mean in sms we cannot create a hyperlink which sends something like the following call on being clicked: intent:#Intent;action=com.myappname.MY_CUSTOM_ACTION;end. Even if I directly put it in sms, I think it won't be clickable, right?Dwinnell
What about using your domain in the scheme? Like org.example:// ? Seems to work fine.Lights
If I want to listen to 'all' urls on http and https for any reason, how can I do it? I don't think using android.host=" * " would work?Moynihan
Does anyone know how to get this to work with all subdomains. I'd like to wildcard the host attribute like ".*.market.android.com", but I don't think it's possible.Overkill
Just to add to @Lumumba comment: Since iOS9 apps there can also handle schemes of type http(s)://Bilbo
@Hyo But still: Google does not own the "intent:" scheme... so Android developers should not use it :)Alabaster
Not all cases need a fallback to the browser. For example, I use a custom scheme for OAuth callbacks. If my app does is not installed, then you would never be authorizing my app...Hilburn
Not sure why @hackbod's comment has been upvoted so much, since it really doesn't make sense. Google doesn't own the "intent:" scheme she's recommending people use, and keeping people from using other custom schemes is solving a "problem" that doesn't exist. I haven't seen any good reason to break the pre-Lollipop behavior except to tie people in to a bunch of Android-specific boilerplate. It sounds purist at first blush, but is just a Microsoft-like "broken by design" move in the last analysis.Hayfork
Microsoft-like "broken by design"?Templet
P
101

I think you'll want to look at the <intent-filter> element of your Manifest file. Specifically, take a look at the documentation for the <data> sub-element.

Basically, what you'll need to do is define your own scheme. Something along the lines of:

<intent-filter>
    <data android:scheme="anton" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" /> <--Not positive if this one is needed
    ...
</intent-filter>

Then you should be able to launch your app with links that begin with the anton: URI scheme.

Paternoster answered 12/8, 2010 at 16:44 Comment(14)
That works great! Do you have any idea how to grab the "useful_info_for_anton_app" once my application is launched from the link?Tropic
Try taking a look at this thread. It has a pretty good example: #2959201Paternoster
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."Mink
Please follow the link which eldarerathis has suggested.It is really helpful.Roomer
The ORDER! As noted in a comment above, the order of the elements is significant and finally worked for me when ordered like this answer.Immure
Ok and if someone knows how to launch an app in separate sandbox? When I launch my app from browser in starts on top of the browser. I need something like launchig apps from Play Market on Open button click, but with url linksReflective
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: https://mcmap.net/q/81883/-launching-custom-android-application-from-android-browser-chrome PS: struggled for days over this.Demoralize
This works perfectly on previous android versions, but not on lollipop, any solution?Rozellarozelle
@Paternoster this works if application is close but if application is running on the background and the activity is different than the one which intent filter attached I could not handle it. How do you manage this to work for in all activities? Do you put intent filter into all of them?Afield
@Paternoster ....hello sir...by yours above code, i only understand to handle the data from the link...Can you please tell me that how can i create a link which contains my data...please help me...I want to create the link with data on button click event..Ombudsman
This answer is outdated..this will not work post chrome 40. The custom scheme has been disabled in chrome due to security issuesBeacon
@Paternoster This is not working for me, you can see my question. #54748713Sidoney
can we app link in android from java script in background, without user interaction?Ruthenic
how to get data which is in the url after launching app using this?Bakelite
A
14

I have a jQuery plugin to launch native apps from web links: https://github.com/eusonlito/jquery.applink

You can use it easily:

<script>
$('a[data-applink]').applink();
</script>

<a href="https://facebook.com/me" data-applink="fb://profile">My Facebook Profile</a>
Akeyla answered 10/9, 2013 at 9:41 Comment(0)
E
13

I also faced this issue and see many absurd pages. I've learned that to make your app browsable, change the order of the XML elements, this this:

<activity
    android:name="com.example.MianActivityName"
    android:label="@string/title_activity_launcher">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <intent-filter>                
        <data android:scheme="http" />     
        <!-- or you can use deep linking like  -->               

        <data android:scheme="http" android:host="xyz.abc.com"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <category android:name="android.intent.category.DEFAULT"/>

    </intent-filter>
</activity>

This worked for me and might help you.

Ebracteate answered 17/9, 2013 at 4:28 Comment(2)
I write XML tag in the same sequence but not able to open chooser dialog when i write my url in android browser.Puppet
i didn't see much difference, and if i use this one it's working perfectly.. Thank you:)Anesthetist
V
6

Here's my recipe:

Create a static HTML that redirects to your requested app URL, put that page on the web.

That way, the links you share are 'real' links as far as Android is concerned ( they will be 'clickable').

You 'share' a regular HTTP link, www.your.server.com/foo/bar.html This URL returns a simple 8 line HTML that redirects to your app's URI (window.location = "blah://kuku") (note that 'blah' doesn't have to be HTTP or HTTPS any more).

Once you get this up and running, you can augment the HTML with all the fancy capabilities as suggested above.

This works with the built-in browser, Opera, and Firefox (haven't tested any other browser). Firefox asks 'This link needs to be opened with an application' (ok, cancel). Other browsers apparently don't worry about security that much, they just open the app, no questions asked.

Vanesavanessa answered 7/10, 2012 at 11:20 Comment(1)
Great! It worked for me. So we added html page with a link to custom scheme that redirects to my app. My link is <a href="iamnearby://register_activate">Activate</a>Adopted
U
5

This method doesn't call the disambiguation dialog asking you to open either your app or a browser.

If you register the following in your Manifest

<manifest package="com.myApp" .. >
  <application ...>
    <activity ...>
      <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="gallery"
          android:scheme="myApp" />
      </intent-filter>
    </activity>
    ..

and click this url from an email on your phone for example

<a href="intent://gallery?directLink=true#Intent;scheme=myApp;package=com.myApp;end"> 
  Click me 
</a>

then android will try to find an app with the package com.myApp that responds to your gallery intent and has a myApp scheme. In case it can't, it will take you to the store, looking for com.myApp, which should be your app.

Urushiol answered 2/6, 2020 at 8:34 Comment(5)
How to go to an android activity?Aloft
The <activity ...> specified in the manifest will open as it is the one that has the <intent-filter> attached to itUrushiol
how can I text it in mobile?Veach
hii, it worked for me but I want to set if app not installed then display some message how to do that in web sideTenure
@Tenure I don't think you can do that because you have no knowledge from the browser (which is not your own app) if an app is installed or not. From your own app you can check if another is installed by seeing if something answers to your intent, but from a 3rd party (in your case, the browser) you don't have a way of obtaining that information.Urushiol
F
4

Once you have the intent and custom url scheme for your app set up, this javascript code at the top of a receiving page has worked for me on both iOS and Android:

<script type="text/javascript">
// if iPod / iPhone, display install app prompt
if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i) ||
    navigator.userAgent.match(/android/i)) {
  var store_loc = "itms://itunes.com/apps/raditaz";
  var href = "/iphone/";
  var is_android = false;
  if (navigator.userAgent.match(/android/i)) {
    store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";
    href = "/android/";
    is_android = true;
  }
  if (location.hash) {
    var app_loc = "raditaz://" + location.hash.substring(2);
    if (is_android) {
      var w = null;
      try {
        w = window.open(app_loc, '_blank');
      } catch (e) {
        // no exception
      }
      if (w) { window.close(); }
      else { window.location = store_loc; }
    } else {
      var loadDateTime = new Date();
      window.setTimeout(function() {
        var timeOutDateTime = new Date();
        if (timeOutDateTime - loadDateTime < 5000) {
          window.location = store_loc;
        } else { window.close(); }
      },
      25);
      window.location = app_loc;
    }
  } else {
    location.href = href;
  }
}
</script>

This has only been tested on the Android browser. I am not sure about Firefox or Opera. The key is even though the Android browser will not throw a nice exception for you on window.open(custom_url, '_blank'), it will fail and return null which you can test later.

Update: using store_loc = "https://play.google.com/store/apps/details?id=com.raditaz"; to link to Google Play on Android.

Frederickfredericka answered 23/11, 2011 at 3:55 Comment(4)
what is the point of the loadDateTime/timeOutDateTime? Does this somehow get around popup blockers or something?Streeter
this doesn't seem to work in my tests, window.open(...) will always open a new window, even if the scheme is not handled.Cribbing
@MattWolfe sorry for the late reply. On iPhone (Safari) no exception is thrown. The timeout is there to close the stale window in Safari that is leftover after the page has redirected to the app. I haven't found a way to have a url open without going through Safari and most other apps that recognize urls like this do the same thing. That was one of the advantages of "deep linking" from Facebook: you don't get that stale leftover window from going through mobile Safari.Frederickfredericka
@jtomson: Interesting. I tested on the Emulator and various devices from Android 2.1 through 3 (at the time). What device and Android version were you testing on?Frederickfredericka
C
4

You may want to consider a library to handle the deep link to your app:

https://github.com/airbnb/DeepLinkDispatch

You can add the intent filter on an annotated Activity like people suggested above. It will handle the routing and parsing of parameters for all of your deep links. For example, your MainActivity might have something like this:

@DeepLink("somePath/{useful_info_for_anton_app}")
public class MainActivity extends Activity {
   ...
}

It can also handle query parameters as well.

Confederacy answered 2/7, 2015 at 18:40 Comment(0)
G
0

Try my simple trick:

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.startsWith("classRegister:")) {                  
                Intent MnRegister = new Intent(getApplicationContext(), register.class); startActivity(MnRegister);
            }               
            view.loadUrl(url);
            return true;
        }

and my html link:

<a href="classRegister:true">Go to register.java</a>

or you can make < a href="classRegister:true" > <- "true" value for class filename

however this script work for mailto link :)

        if (url.startsWith("mailto:")) {
            String[] blah_email = url.split(":");
            Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("text/plain");
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{blah_email[1]});
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, what_ever_you_want_the_subject_to_be)");
            Log.v("NOTICE", "Sending Email to: " + blah_email[1] + " with subject: " + what_ever_you_want_the_subject_to_be);
            startActivity(emailIntent);
        }
Glairy answered 19/11, 2011 at 7:32 Comment(1)
This is essentially a call to a JavascriptInterface with the workaround, this is the right workaround if you need to support 2.3 where JavascriptInterface is bugged.Arenas
P
0

Just want to open the app through browser? You can achieve it using below code:

HTML:

<a href="intent:#Intent;action=packageName;category=android.intent.category.DEFAULT;category=android.intent.category.BROWSABLE;end">Click here</a>

Manifest:

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

This intent filter should be in Launcher Activity.

If you want to pass the data on click of browser link, just refer this link.

Pericycle answered 6/1, 2021 at 12:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.