1page.title=App Links
2page.image=images/cards/card-app-linking_2x.png
3page.keywords=applinking, deeplinks, intents
4@jd:body
5
6<div id="qv-wrapper">
7  <div id="qv">
8    <h2>In this document</h2>
9      <ol>
10        <li><a href="#url-handling">Understanding URL Request Handling</a> </li>
11        <li><a href="#intent-handler">Create an Intent Handler for URLs</a></li>
12        <li><a href="#request-verify">Request App Links Verification</a></li>
13        <li><a href="#web-assoc">Declare Website Associations</a></li>
14        <li><a href="#testing">Testing App Links</a></li>
15      </ol>
16  </div>
17</div>
18
19
20<p>
21  The M Developer Preview introduces a new option for handling web site links, allowing clicked
22  links to go directly to the website's official app, instead of asking the user to chose how to
23  handle the link. This feature saves the user time and helps developers deliver a better
24  experience. Users can also select whether an app should always open specific types of links
25  automatically or prompt the user each time.
26</p>
27
28<p>
29  Handling links automatically requires the cooperation of app developers and website owners.
30  Developers must configure their apps to declare connections with websites and request
31  verification. Website owners can publish a
32  Digital Asset Links file
33  to allow Android to verify the association of apps with their sites. The general steps for
34  creating verified app links are as follows:
35</p>
36
37<ol>
38  <li>Create intent filters within your app for your website URLs</li>
39  <li>Configure your app to request verification of app links</li>
40  <li>Publish a Digital Asset Links JSON file on your websites</li>
41</ol>
42
43<h2 id="url-handling">Understanding URL Request Handling</h2>
44
45<p>
46  The app links feature allows your app to become the default handler for your website URLs, as
47  long as the user has not already chosen an app to handle that URL pattern. When a web URI intent
48  is invoked through a clicked link or programatic request, the Android system determines what app
49  is used to handle the intent. The system use these criteria, in order, to determine how to handle
50  the request:
51</p>
52
53<ol>
54  <li>
55    <strong>User has set app link associations</strong>: If the user has designated an app to
56    handle app links, the system passes the web URI request to that app. Users set this association
57    by opening <strong>Settings &gt; Apps &gt; Configure apps (gear icon) &gt; App links</strong>,
58    then selecting an app to use and configuring it's <strong>App links</strong> property to the
59    <em>Open in this app</em> option.
60  </li>
61
62  <li>
63    <strong>No association set by user and a single supporting app</strong>: If the user
64    has not set a preference that matches the web URI request, and there is only one app declaring
65    support for the intent’s URI pattern, the system passes the request to that app.
66  </li>
67
68  <li>
69    <strong>No association set by user and multiple supporting apps</strong>: If there is
70    no explicit user preference and there are multiple apps declaring support for the web URI
71    pattern, the system prompts the user to select one of the available apps
72  </li>
73</ol>
74
75<p>
76  In case #2 (no user setting and no other app handlers), if an app is newly installed and verified
77  as a handler for this type of link, the system sets it as the default handler. In the other two
78  cases, the system behavior is the same, regardless of the presence of a verified app link
79  handler.
80</p>
81
82
83<h2 id="intent-handler">Create an Intent Handler for URLs</h2>
84
85<p>
86  App links are based on the <a href="{@docRoot}guide/components/intents-filters.html">Intent</a>
87  framework, which enables apps to handle requests from the system or other apps. Multiple apps may
88  declare matching web link URI patterns in their intent filters. When a user clicks on a web link
89  that does not have a default launch handler, the platform selects an app to handle the request,
90  based on the criteria described in the previous section.
91</p>
92
93<p>
94  To enable your app to handle links, use intent filters in your app manifest to declare the URI
95  patterns to be handled by your app. The following sample code shows an intent filter that can
96  handle links to {@code http://www.android.com} and {@code https://www.android.com}:
97</p>
98
99<pre>
100  &lt;activity ...&gt;
101      &lt;intent-filter&gt;
102          &lt;action android:name="android.intent.action.VIEW" /&gt;
103          &lt;category android:name="android.intent.category.DEFAULT" /&gt;
104          &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
105          &lt;data android:scheme="http" /&gt;
106          &lt;data android:scheme="https" /&gt;
107          &lt;data android:host="www.android.com" /&gt;
108      &lt;/intent-filter&gt;
109  &lt;/activity&gt;
110</pre>
111
112<p>
113  As shown in the example above, intent filters for app links must declare an {@code android:scheme}
114  value of either {@code http} or {@code https}, or both. The filter should not declare
115  any other schemes. The filter must also include the {@code android.intent.action.VIEW}; and
116  {@code android.intent.category.BROWSABLE} category names.
117</p>
118
119<p>
120  This manifest declaration defines the connection between your app and a website. However, in
121  order to have the system treat your app as the default handler for a set of URLs, you must
122  also request that the system verify this connection, which is explained in the next section.
123</p>
124
125
126<h2 id="request-verify">Request App Links Verification</h2>
127
128<p>
129  In addition to declaring an association between your app and a web site using intent filters,
130  your app must also request automatic verification with an additional manifest declaration. When
131  this declaration is set, the Android system attempts to verify your app after it is installed.
132  If the verification succeeds, and the user has not set a preference for your website URLs, the
133  system automatically routes those URL requests to your app.
134</p>
135
136<p>
137  The system performs app link verifications by comparing the host names in the data elements of
138  the app’s intent filters against the Digital Asset Links files ({@code assetlinks.json}) hosted
139  on the respective web domains. To enable the system to verify a host, make sure that your intent
140  filter declarations include the {@code android.intent.action.VIEW} intent action and {@code
141  android.intent.category.BROWSABLE} intent category.
142</p>
143
144
145<h3 id="config-verify">Enabling automatic verification</h3>
146
147<p>
148  To enable link handling verification for your app, set the {@code android:autoVerify} attribute to
149  {@code true} on at least one of the web URI intent filters in your app manifest, as shown in the
150  following manifest code snippet:
151</p>
152
153<pre>
154&lt;activity ...&gt;
155
156    &lt;intent-filter <strong>android:autoVerify="true"</strong>&gt;
157        &lt;action android:name="android.intent.action.VIEW" /&gt;
158        &lt;category android:name="android.intent.category.DEFAULT"gt;
159        &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
160        &lt;data android:scheme="http" android:host="www.android.com" /&gt;
161        &lt;data android:scheme="https" android:host="www.android.com" /&gt;
162    &lt;/intent-filter&gt;
163
164&lt;/activity&gt;
165</pre>
166
167<p>
168  When the {@code android:autoVerify} attribute is set, the system attempts to verify all hosts
169  associated with web URI’s in all of your app's intent filters when the app is installed. The
170  system treats your app as the default handler for the specified URI pattern only if it
171  successfully verifies <em>all</em> app link patterns declared in your manifest.
172</p>
173
174
175<h3 id="multi-host">Supporting app linking for multiple hosts</h3>
176
177<p>
178  The system must be able to verify each host specified in the app’s web URI intent filters’ data
179  elements against the Digital Asset Links files hosted on the respective web domains. If any
180  verification fails, the app is not verified to be a default handler for any of the web URL
181  patterns defined in its intent filters. For example, an app with the following intent filters
182  would fail verification if an {@code assetlinks.json} file were not found at both
183  {@code https://www.domain1.com/.well-known/assetlinks.json} and
184  {@code https://www.domain2.com/.well-known/assetlinks.json}:
185</p>
186
187<pre>
188&lt;application&gt;
189
190  &lt;activity android:name=”MainActivity”&gt;
191    &lt;intent-filter <strong>android:autoVerify="true"</strong>&gt;
192      &lt;action android:name="android.intent.action.VIEW" /&gt;
193      &lt;category android:name="android.intent.category.DEFAULT" /&gt;
194      &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
195      &lt;data android:scheme="http" android:host="www.domain1.com" /&gt;
196      &lt;data android:scheme="https" android:host="www.domain1.com" /&gt;
197    &lt;/intent-filter&gt;
198  &lt;/activity&gt;
199  &lt;activity android:name=”SecondActivity”&gt;
200    &lt;intent-filter&gt;
201      &lt;action android:name="android.intent.action.VIEW" /&gt;
202      &lt;category android:name="android.intent.category.DEFAULT" /&gt;
203      &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
204      &lt;data android:scheme="https" android:host="www.domain2.com" /&gt;
205    &lt;/intent-filter&gt;
206  &lt;/activity&gt;
207
208&lt;/application
209</pre>
210
211
212<h3 id="multi-subdomain">Supporting app linking for multiple subdomains</h3>
213
214<p>
215  The Digital Asset Links protocol treats subdomains as unique, separate hosts. If your intent
216  filter lists both the {@code www.example.com} and {@code mobile.example.com} subdomains as
217  schemes, you must host separate {@code assetlink.json} file on each subdomain. For example, an
218  app with the following intent filter declaration would pass verification only if the website
219  owner published valid {@code assetlinks.json} files at both
220  {@code https://www.example.com/.well-known/assetlinks.json} and
221  {@code https://mobile.example.com/.well-known/assetlinks.json}:
222</p>
223
224<pre>
225&lt;application&gt;
226  &lt;activity android:name=”MainActivity”&gt;
227    &lt;intent-filter <strong>android:autoVerify="true"</strong>&gt;
228      &lt;action android:name="android.intent.action.VIEW" /&gt;
229      &lt;category android:name="android.intent.category.DEFAULT" /&gt;
230      &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
231      &lt;data android:scheme="http" android:host="www.example.com" /&gt;
232      &lt;data android:scheme="https" android:host="mobile.example.com" /&gt;
233    &lt;/intent-filter&gt;
234  &lt;/activity&gt;
235&lt;/application&gt;
236</pre>
237
238
239<h2 id="web-assoc">Declare Website Associations</h2>
240
241<p>
242  For app link verification to be successful, website owners must declare associations
243  with apps. A site owner declares the relationship to an app by hosting a Digital Asset Links JSON
244  file, with the name {@code assetlinks.json}, at the following well-known location on the domain:
245</p>
246
247<pre>
248  https://<em>domain</em>[:<em>optional_port</em>]/.well-known/assetlinks.json
249</pre>
250
251<p class="note">
252  <strong>Important:</strong> With M Preview 3 and the Android 6.0 (API level 23) release, the JSON
253  file is verified via the encrypted HTTPS protocol. Make sure that your hosted file can be
254  accessed over an HTTPS connection, regardless of whether your app's intent filter declares an
255  {@code android:scheme} setting of {@code http}, {@code https} or both.
256</p>
257
258<p>
259  A Digital Asset Links JSON file indicates the Android apps that are associated with the web site.
260  The JSON file identifies associated apps with the following fields:
261</p>
262
263<ul>
264  <li>{@code package_name}: The package name declared in the app's manifest.</li>
265
266  <li>{@code sha256_cert_fingerprints}: The SHA256 fingerprints of your app’s signing certificate.
267    You can use the Java keytool to generate the fingerprint using the following command:
268    <pre>keytool -list -v -keystore my-release-key.keystore</pre>
269    This field supports multiple fingerprints, which can be used to support different versions
270    of your app, such as debug and production builds.
271  </li>
272</ul>
273
274<p>
275  The following example {@code assetlinks.json} file grants link opening rights to a
276  {@code com.example} Android application:
277</p>
278
279<pre>
280  [{
281    "relation": ["delegate_permission/common.handle_all_urls"],
282    "target": {
283      "namespace": "android_app",
284      "package_name": "com.example",
285      "sha256_cert_fingerprints":
286      ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
287    }
288  }]
289</pre>
290
291
292<h3 id="multiple-apps">Associating a website with multiple apps</h3>
293
294<p>
295  A website can declare associations with multiple apps within the same {@code assetlinks.json}
296  file. The following file listing shows an example of a statement file that declares association
297  with two, separate apps and is hosted at
298  <code>https://www.example.com/.well-known/assetlinks.json</code>:
299</p>
300
301<pre>
302[{
303  "relation": ["delegate_permission/common.handle_all_urls"],
304  "target": {
305    "namespace": "android_app",
306    "package_name": <strong>"example.com.puppies.app"</strong>,
307    "sha256_cert_fingerprints":
308    ["<strong>14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5</strong>"]
309  }
310  },
311  {
312  "relation": ["delegate_permission/common.handle_all_urls"],
313  "target": {
314    "namespace": "android_app",
315    "package_name": "<strong>example.com.monkeys.app</strong>",
316    "sha256_cert_fingerprints":
317    ["<strong>14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5</strong>"]
318  }
319}]
320</pre>
321
322<p>
323  When multiple apps handle links to the same host, the system determines which one to use for
324  a given link based on the intent filters defined in each app’s manifest. Different apps may
325  handle links for different resources under the same web host. For example, app1 may
326  declare an intent filter for {@code https://example.com/articles}, and app2 may declare
327  an intent filter for {@code https://example.com/videos}.
328</p>
329
330<p class="note">
331  <strong>Note:</strong> Multiple apps associated with a domain may be signed with the same or
332  different certificates.
333</p>
334
335
336<h3 id="multi-site">Associating multiple websites with a single app</h3>
337
338<p>
339  Multiple websites can declare associations with the same app in their respective {@code
340  assetlinks.json} files. The following file listings show an example of how to declare the
341  association of domain1 and domain2 with app1:
342</p>
343
344<pre>
345https://www.domain1.com/.well-known/assetlinks.json
346
347[{
348  "relation": ["delegate_permission/common.handle_all_urls"],
349  "target": {
350    "namespace": "android_app",
351    "package_name": "<strong>com.mycompany.app1</strong>",
352    "sha256_cert_fingerprints":
353    ["<strong>14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5</strong>"]
354  }
355}]
356</pre>
357
358<pre>
359https://www.domain2.com/.well-known/assetlinks.json
360
361[{
362  "relation": ["delegate_permission/common.handle_all_urls"],
363  "target": {
364    "namespace": "android_app",
365    "package_name": "<strong>com.mycompany.app1</strong>",
366    "sha256_cert_fingerprints":
367    ["<strong>14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5</strong>"]
368  }
369}]
370</pre>
371
372
373
374<h2 id="testing">Testing App Links</h2>
375
376<p>
377  When implementing the app linking feature, you should test the linking functionality to
378  make your app can be successfully associated with your websites and handle URL requests
379  as you expect.
380</p>
381
382
383<h3 id="test-hosts">Confirm the list of hosts to verify</h3>
384
385<p>
386  When testing, you should confirm the list of associated hosts that the system should verify
387  for your app. Make a list of all web URI’s in intent-filters in your manifest that
388  includes the following:
389</p>
390
391<ul>
392  <li>{@code android:scheme} attribute with a value of {@code http} or {@code https}
393  </li>
394  <li>{@code android:host} attribute with a domain URI pattern
395  </li>
396  <li>{@code android.intent.action.VIEW} category element
397  </li>
398  <li>{@code android.intent.category.BROWSABLE} category element
399  </li>
400</ul>
401
402<p>
403  Use this list to check that a Digital Asset Links JSON file is provided on each named host
404  and subdomain.
405</p>
406
407
408<h3 id="test-dal-files">Confirm the Digital Asset Links files</h3>
409
410<p>
411  For each website, confirm that the Digital Asset Links JSON file is properly hosted and
412  defined by using the Digital Asset Links API:
413</p>
414
415<pre>
416https://digitalassetlinks.googleapis.com/v1/statements:list?
417   source.web.site=https://<strong>&lt;domain1&gt;:&lt;port&gt;</strong>&amp;
418   relation=delegate_permission/common.handle_all_urls
419</pre>
420
421
422<h3 id="test-intent">Testing a web URI intent</h3>
423
424<p>
425  Once you have confirmed the list of websites to associate with your app, and you have confirmed
426  that the hosted JSON file is valid, install the app on your device. Wait at least 20 seconds for
427  the asynchronous verification process to complete. Use the following command to check
428  if the system verified your app and set the correct link handling policies:
429</p>
430
431<pre>
432adb shell am start -a android.intent.action.VIEW \
433    -c android.intent.category.BROWSABLE \
434    -d "http://&lt;domain1&gt;:&lt;port&gt;"
435</pre>
436
437
438<h3 id="check-link-policies">Check link policies</h3>
439
440<p>
441  As part of your testing process, you can check the current system settings for link handling.
442  Use the following command to get a listing of link-handling policies for all applications:
443</p>
444
445<pre>
446  adb shell dumpsys package domain-preferred-apps
447  --or--
448  adb shell dumpsys package d
449</pre>
450
451<p class="note">
452  <strong>Note:</strong> Make sure you wait at least 20 seconds after installation of your app to
453  allow for the system to complete the verification process.
454</p>
455
456<p>
457  The command returns a listing of each user or profile defined on the device,
458  indicated by a header in the following format:
459</p>
460
461<pre>
462App linkages for user 0:
463</pre>
464
465<p>
466  Following this heading, the output lists the link-handling settings for that user in this format:
467</p>
468
469<pre>
470Package: com.android.vending
471Domains: play.google.com market.android.com
472Status: always : 200000002
473</pre>
474
475<p>This listing indicates the what apps are associated with what domains for that user, as
476  described below:</p>
477
478<ul>
479  <li>{@code Package} - Identifies an app by its package name, as declared in its manifest.
480  </li>
481  <li>{@code Domains} - Shows the full list of hosts whose web links this app handles.
482  </li>
483  <li>{@code Status} - Shows the current link-handling setting for this app. An app that set {@code
484  android:autoVerify="true"} value and passed verification is shown with a status of {@code
485  always}. The hexadecimal number after this status is related to the Android system's record of
486  the user’s app linkage preferences. This value is not relevant for interpreting whether the
487  verification operation passed.
488  </li>
489</ul>
490
491<p class="note">
492  <strong>Note:</strong>It is possible for a user to change the app link settings for an app
493  before the verification operation has completed. If this
494  situation occurs, you may see a false positive for a successful verification, even though
495  verification has failed. However, the user has already explicitly enabled the app to open
496  supported links without asking. In this case, no dialog is shown and the link goes directly to
497  your app, but only because explicit user preferences take precedence.
498</p>
499
500
501
502<h3 id="test-example">Test example</h3>
503
504<p>
505  For app link verification to succeed, the system must be able to verify your app with all of
506  the websites referenced in your app’s intent filters, that meet the criteria for app links.
507  The following example manifest snippet shows app configuration with several app links defined:
508</p>
509
510<pre>
511  &lt;application&gt;
512
513      &lt;activity android:name=”MainActivity”&gt;
514          &lt;intent-filter <strong>android:autoVerify="true"</strong>&gt;
515              &lt;action android:name="android.intent.action.VIEW" /&gt;
516              &lt;category android:name="android.intent.category.DEFAULT" /&gt;
517              &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
518              &lt;data android:scheme="http" android:host="www.example.com" /&gt;
519              &lt;data android:scheme="https" android:host="mobile.example.com" /&gt;
520          &lt;/intent-filter&gt;
521          &lt;intent-filter&gt;
522              &lt;action android:name="android.intent.action.VIEW" /&gt;
523              &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
524              &lt;data android:scheme="http" android:host="www.example2.com" /&gt;
525          &lt;/intent-filter&gt;
526      &lt;/activity&gt;
527
528      &lt;activity android:name=”SecondActivity”&gt;
529          &lt;intent-filter&gt;
530              &lt;action android:name="android.intent.action.VIEW" /&gt;
531              &lt;category android:name="android.intent.category.DEFAULT" /&gt;
532              &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
533              &lt;data android:scheme="http" android:host="account.example.com" /&gt;
534          &lt;/intent-filter&gt;
535      &lt;/activity&gt;
536
537      &lt;activity android:name=”ThirdActivity”&gt;
538        &lt;intent-filter&gt;
539            &lt;action android:name="android.intent.action.VIEW" /&gt;
540            &lt;category android:name="android.intent.category.DEFAULT" /&gt;
541            &lt;data android:scheme="http" android:host="map.example.com" /&gt;
542        &lt;/intent-filter&gt;
543        &lt;intent-filter&gt;
544            &lt;action android:name="android.intent.action.VIEW" /&gt;
545            &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
546            &lt;data android:scheme="market" android:host="example.com" /&gt;
547        &lt;/intent-filter&gt;
548      &lt;/activity&gt;
549
550  &lt;/application&gt;
551</pre>
552
553<p>
554  The list of hosts that the platform would attempt to verify from the above manifest is:
555</p>
556
557<pre>
558  www.example.com
559  mobile.example.com
560  www.example2.com
561  account.example.com
562</pre>
563
564<p>
565  The list of hosts that the platform would not attempt to verify from the above manifest is:
566</p>
567
568<pre>
569  map.example.com (it does not have android.intent.category.BROWSABLE)
570  market://example.com (it does not have either an “http” or “https” scheme)
571</pre>
572