Как реализовать ссылки на приложения Android с подстановочными доменами?

В Android есть руководство по внедрению ссылок на приложения. То есть, если мое приложение объявляет, что оно обрабатывает определенные веб-ссылки, и я пытаюсь открыть эту ссылку в любом другом приложении, система перехватывает это и направляет пользователя прямо в мое приложение, а не в браузер, чтобы я мог отображать соответствующий контент прямо в своем приложении. Очень кстати.

Чего мне не хватает в руководстве, так это двух вещей:

  1. Как реализовать ссылки на приложения с подстановочными доменами. Я хотел бы, чтобы мое приложение обрабатывало ссылки на *.example.com, то есть все ссылки на subdomains из example.com (test.example.com, something.example.com и т. д.);

  2. Как реализовать ссылки приложений только на определенные пути на моем сайте. Например, я хочу перехватить test.example.com/something, но не test.example.com/other. Первый должен прийти в мое приложение, второй — в мой браузер;

Соответствующее руководство по iOS показывает, что iOS обрабатывает оба этих сценария (хотя часть подстановочных знаков была неясна из документов, и мне пришлось уточнить у службы поддержки Apple, что вам нужно поместить файл ассоциации в корневой домен, а не в поддомен).

Могут ли ссылки на приложения Android обрабатывать домены с подстановочными знаками и только подмножество путей?


person Jaanus    schedule 21.09.2016    source источник
comment
В последнем случае попробуйте android:path для элемента <data>.   -  person CommonsWare    schedule 21.09.2016
comment
Что касается доменов/хостов с подстановочными знаками, я вижу некоторые ссылки на подстановочные знаки хоста в источнике Intent Filter здесь - android.googlesource.com/platform/frameworks/base/+/master/core/. Прежде чем сделать вывод, что это невозможно, может быть, кто-то может взглянуть на это и посмотреть, уместно ли это в контексте этого вопроса.   -  person Jaanus    schedule 26.09.2016
comment
Если вы имеете в виду mWild и тому подобное в AuthorityEntry, эта реализация match() кажется неправильной. Но, помимо этого, наличие рабочих подстановочных знаков в <intent-filter>/IntentFilter необходимо, но недостаточно. Возможно, фильтры поддерживают подстановочные знаки, а ссылки на приложения — нет.   -  person CommonsWare    schedule 26.09.2016
comment
Я не знаю, было ли недавно обновление этого документа, но я прочитал по ссылке, размещенной выше, что он действительно поддерживает подстановочный знак для атрибута хоста в тегах данных.   -  person carlosavoy    schedule 09.02.2017


Ответы (3)


  1. Обновление: теперь вы можете обрабатывать домены с подстановочными знаками, используя ссылки на цифровые активы.

аурилио объяснил это в своем новом ответе

Весь процесс задокументирован здесь: https://developer.android.com/training/app-links/verify-site-associations

Подводя итог, можно сказать, что теперь вы можете использовать подстановочный знак в теге host и вы должны загрузить файл json с именем assetlinks. json в папку/маршрут /.well-known в вашем корневом домене.

В качестве альтернативы, если вы объявляете свое имя хоста с помощью подстановочного знака (например, *.example.com), вы должны опубликовать свой файл assetslinks.json в корневом имени хоста (example.com).

Вам также потребуется добавить атрибут android:autoVerify="true" в тег intent-filter.

Вот весь пример на стороне Android:

<application>
  <activity android:name=”MainActivity”>
    <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.com" />
    </intent-filter>
  </activity>
</application>

Вот предыдущий ответ от 2016 года: К сожалению, Android не может обрабатывать домены с подстановочными знаками.

Если вы посмотрите руководство по API для тега data (https://developer.android.com/guide/topics/manifest/data-element.html), вы можете видеть, что они упоминают, что подстановочные знаки доступны для pathPattern и mimeType, но не для хоста.

Дело в том, что, как объяснил CommonsWare в другом сообщении на эту тему (https://stackoverflow.com/a/34068591/4160079 ),

домены проверяются во время установки, и нет возможности добавить новые домены, кроме как путем отправки новой версии приложения с новым манифестом.

Таким образом, вам придется вручную перечислить все доступные субдомены и обновлять приложение всякий раз, когда запускается новый субдомен.

Вот как вы объявляете несколько поддоменов:

 <activity android:name="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="http" />
        <data android:host="subdomain1.example.com" />
        <data android:host="subdomain2.example.com" />
        <data android:host="subdomain3.example.com" />
    </intent-filter>
</activity>

  1. Да, вы можете обрабатывать только часть путей

Это та же идея, просто перечислите нужные пути, используя атрибут path (опять же, см. руководство по API тега data выше).

Если вы используете строки запроса или параметры пути, предпочтительнее использовать pathPrefix.

При необходимости вы можете использовать здесь подстановочные знаки, выбрав вместо этого pathPattern.

Часть пути URI, которая должна начинаться с /. Атрибут path указывает полный путь, который сопоставляется с полным путем в объекте Intent. Атрибут pathPrefix указывает частичный путь, который сопоставляется только с начальной частью пути в объекте Intent. Атрибут pathPattern указывает полный путь, который сопоставляется с полным путем в объекте Intent, но может содержать следующие подстановочные знаки: Звездочка ('') соответствует последовательности 0 множеству вхождений непосредственно предшествующего символа. Точка, за которой следует звездочка (""."), соответствует любой последовательности от 0 до многих символов.

Вот несколько примеров:

 <activity android:name="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="http" />
        <data android:host="subdomain1.example.com" />
        <data android:host="subdomain2.example.com" />
        <data android:host="subdomain3.example.com" />
        <data android:path="/path1" /> <!-- matches /path1 only -->
        <data android:pathPrefix="/path2" /> <!-- matches /path2, /path2/something or also /path2?key=value etc... -->
        <data android:pathPattern="/wild.*" /> <!-- matches /wild, /wild3, /wilderness etc... -->
    </intent-filter>
</activity>
person APE    schedule 25.09.2016
comment
См. мой комментарий к вопросу о подстановочных доменах. Похоже, что в источнике фильтра Intent есть какой-то код, связанный с подстановочными знаками. Это актуально? - person Jaanus; 26.09.2016
comment
Этот код, связанный с подстановочными знаками, который вы упомянули, работает для пользовательских схем. Однако в случае со ссылками на приложения сразу после установки выполняется проверка для каждого домена. - person APE; 30.09.2016
comment
подстановочный знак также доступен для хоста. По ссылке, которой вы поделились. - person Mayur More; 16.08.2018
comment
@MayurMore Вы правы - похоже, это было обновлено с тех пор, как я опубликовал свой ответ. Я отредактирую свой ответ - а пока я бы посоветовал посмотреть ответ Аурилио - person APE; 18.08.2018
comment
android:autoVerify=true доступно только из API 23 - person Nicola Gallazzi; 10.09.2019

Android не может обрабатывать подстановочный домен как таковой (согласно их документации на сегодняшний день), но это ответит на ваш запрос о включении и исключении определенных /paths.

Чтобы реализовать глубокую ссылку для URL-адресов, подобных

http://example.com/gizmos?1234, 
http://example.com/gizmos/1234,
http://example.com/gizmos/toys/1234,
etc.

Ваш XML должен выглядеть примерно так:

<activity android:name="com.example.android.GizmosActivity" android:label="@string/title_gizmos" > 
    
    <intent-filter android:label="@string/filter_title_viewgizmos">
        <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 "example://gizmos” --> 
    
        <data android:scheme="example" android:host="gizmos" />
    </intent-filter>
    <intent-filter android:label="@string/filter_title_viewgizmos">
        <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/gizmos” -->
        <data android:scheme="http" android:host="example.com" android:pathPrefix="/gizmos" /> 
    </intent-filter> 
</activity>

Теперь, учитывая, что вы смогли этого добиться, вот как вы ограничиваете доступ к частям содержимого вашего приложения:

<?xml version="1.0" encoding="utf-8"?>
<search-engine xmlns:android="http://schemas.android.com/apk/res/android">
    <noindex uri="http://example.com/gizmos/hidden_uri"/>
    <noindex uriPrefix="http://example.com/gizmos/hidden_prefix"/>
    <noindex uri="gizmos://hidden_path"/>
    <noindex uriPrefix="gizmos://hidden_prefix"/>
</search-engine>

И часть манифеста-

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.Gizmos">
    <application> 
        <activity android:name="com.example.android.GizmosActivity" android:label="@string/title_gizmos" >
            <intent-filter android:label="@string/filter_title_viewgizmos">
            <action android:name="android.intent.action.VIEW"/> ... 
        </activity> 
            <meta-data android:name="search-engine" android:resource="@xml/noindex"/> 
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

Для получения более подробной информации и объяснения этого примера вы можете взглянуть на-

Диплинкинг Android

Надеюсь, это поможет, счастливого кодирования

person bozzmob    schedule 25.09.2016
comment
Я не вижу здесь ничего о подстановочных доменах. - person Jaanus; 25.09.2016
comment
Android не может обрабатывать домены с подстановочными знаками как таковые, но это было сделано для вашего включения и исключения определенных /paths . - person bozzmob; 26.09.2016

Цитата из: https://developer.android.com/training/app-links/verify-site-associations.html

В качестве альтернативы, если вы объявляете свое имя хоста с помощью подстановочного знака (например, *.example.com), вы должны опубликовать свой файл assetslinks.json в корневом имени хоста (example.com). Например, приложение со следующим фильтром намерений пройдет проверку для любого подимени example.com (например, foo.example.com), если файл assetslinks.json опубликован по адресу https://example.com/. .well-known/assetlinks.json:

<application>
  <activity android:name=”MainActivity”>
    <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="www.example.com" />
      <data android:scheme="https" android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>
person aurilio    schedule 19.04.2018