Adicionar filtros de intent para App Links

Os links de apps são links diretos que usam o esquema HTTP ou HTTPS e são verificados pelo Android como associados ao seu site. Para registrar o app para processar links, siga estas etapas:

  1. Adicione um ou mais filtros de intent ao manifesto do app que especifiquem o domínio ou os URLs do seu site.
  2. Adicione o autoVerify="true"attribute aos elementos do filtro de intent. Isso sinaliza ao sistema que ele deve tentar verificar o esquema e os domínios de host em relação à configuração assetlinks.json do seu site.
  3. Declarar associações de sites.

Veja um exemplo de declaração de link do app com esquemas e hosts, além de autoVerify="true:

<activity
    android:name=".MainActivity"
    android:exported="true"
    ...>
    <!-- Make sure you explicitly set android:autoVerify to "true". -->
    <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" />

        <!-- If a user clicks on a link that uses the "http" scheme, your
             app should be able to delegate that traffic to "https". -->
        <!-- Do not include other schemes, as this will prevent verification. -->
        <data android:scheme="http" />
        <data android:scheme="https" />

        <!-- Include one or more domains that should be verified. -->
        <data android:host="www.example.com" />
        <data android:host="*.example.com" />
    </intent-filter>
</activity>

Pontos principais sobre o código

  • AutoVerify: o atributo android:autoVerify="true" é obrigatório para Links do app. Ele sinaliza ao sistema que ele deve tentar verificar a associação entre o app e os esquemas e domínios especificados nas tags <data>. É recomendável adicionar autoVerify="true a todos os filtros de intent que você quer que sejam verificáveis.
  • Elementos de dados: cada filtro de intent de links de apps precisa incluir um ou mais elementos <data> que especificam os esquemas e formatos de host que correspondem ao domínio do site verificável.
  • Esquemas: o filtro de intent precisa incluir elementos <data> para os esquemas http e https.
  • Hosts: é possível adicionar elementos <data> para corresponder a um ou mais hosts. Use um caractere curinga (*) para corresponder a vários subdomínios (como *.example.com). O sistema vai tentar verificar cada host em relação ao arquivo assetlinks.json no seu site. Qualquer roteamento no nível do caminho precisa ser processado pelo arquivo assetlinks.json (consulte a seção de práticas recomendadas abaixo).

  • Vários hosts: se você declarar vários domínios hospedados, o sistema (no Android 12 ou mais recente) vai tentar verificar cada um deles. Se algum host for verificado, o app vai se tornar o gerenciador padrão para links desse host. No Android 11 e versões anteriores, a verificação falha se pelo menos um host não puder ser verificado.

  • Vários filtros de intent: é importante criar filtros separados quando sua intenção é declarar URLs exclusivos (como uma combinação específica de esquema e host), porque vários elementos <data> no mesmo filtro de intent são mesclados para considerar todas as variações dos atributos combinados.

Considerações sobre as regras de filtro de manifesto

Se você estiver configurando filtros para uso com links dinâmicos de apps no Android 15 e versões mais recentes, é importante lembrar que as regras dinâmicas declaradas no arquivo assetlinks.json do lado do servidor não podem expandir o escopo das regras de URL que você declara estaticamente no manifesto do app.

Por isso, recomendamos usar esta abordagem:

  • No manifesto do app, defina o escopo mais amplo possível, por exemplo, declarando apenas o esquema e o domínio.
  • Confie nas regras do assetlinks.json do lado do servidor para um refinamento adicional, como o roteamento no nível do caminho.

Com essa configuração ideal, você poderá adicionar dinamicamente novos caminhos de links do app no arquivo assetlinks.json conforme necessário, sabendo que eles se encaixam no escopo amplo que você definiu no manifesto do app.

Suporte a links de apps para vários hosts

O sistema precisa ser capaz de verificar o host especificado nos elementos de dados dos filtros de intent de URL do app em relação aos arquivos do Digital Asset Links hospedados nos respectivos domínios da Web nesse filtro de intent. Se a verificação falhar, o sistema vai usar o comportamento padrão para resolver a intent, conforme descrito em Criar links diretos para conteúdo de app. No entanto, o app ainda pode ser verificado como um gerenciador padrão para qualquer um dos padrões de URL definidos nos outros filtros de intent do app.

Por exemplo, um app com os filtros de intent abaixo só passaria na verificação para https://www.example.com se um arquivo assetlinks.json fosse encontrado em https://www.example.com/.well-known/assetlinks.json, mas não em https://www.example.net/.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="http" />
      <data android:scheme="https" />
      <data android:host="www.example.com" />
    </intent-filter>
  </activity>
  <activity android:name="SecondActivity">
    <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="https" />
     <data android:host="www.example.net" />
    </intent-filter>
  </activity>

</application>

Suporte à vinculação de apps para vários subdomínios

O protocolo Digital Asset Links trata os subdomínios nos filtros de intent como hosts exclusivos e separados. Portanto, se o filtro de intent listar vários hosts com subdomínios diferentes, você precisará publicar um assetlinks.json válido em cada domínio. Por exemplo, o filtro de intent a seguir inclui www.example.com e mobile.example.com como hosts de URL de intent aceitos. Portanto, um assetlinks.json válido precisa ser publicado em https://www.example.com/.well-known/assetlinks.json e https://mobile.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" />
      <data android:scheme="https" />
      <data android:host="www.example.com" />
      <data android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>

Como alternativa, se você declarar o nome do host com um caractere curinga (como *.example.com), será necessário publicar o arquivo assetlinks.json no nome do host raiz (example.com). Por exemplo, um app com o filtro de intent abaixo vai passar na verificação de qualquer subnome de example.com (como foo.example.com), desde que o arquivo assetlinks.json seja publicado em 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" />
      <data android:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

Verificar se há vários apps associados ao mesmo domínio

Se você publicar vários apps, cada um associado ao mesmo domínio, todos eles poderão ser verificados. No entanto, se os apps puderem resolver exatamente o mesmo host de domínio e caminho, assim como ocorre com as versões Lite e completas de um app, apenas o app instalado mais recentemente poderá resolver intents da Web para o domínio.

Nesse caso, verifique se há possíveis apps conflitantes no dispositivo do usuário, desde que você tenha a visibilidade de pacote necessária. Em seguida, no app, mostre uma caixa de diálogo de seletor personalizada que contenha os resultados da chamada de queryIntentActivities. O usuário pode selecionar o app preferido na lista de apps correspondentes que aparece na caixa de diálogo.

Os recursos de link dinâmico para apps, incluindo regras de correspondência avançadas em assetlinks.json e o uso de <uri-relative-filter-group>, só são totalmente compatíveis com o Android 15 (nível 35 da API) e versões mais recentes.

No Android 14 (nível 34 da API) e versões anteriores, o sistema considera apenas o scheme e o host declarados nos elementos <data> do manifesto para a verificação de links de apps. As regras, exclusões e atualizações dinâmicas específicas do caminho de assetlinks.json não são aplicadas.

Isso significa que, se o manifesto especificar apenas scheme e host, o app poderá capturar inesperadamente todos os caminhos do domínio verificado no Android 14 e versões anteriores, independentemente das regras específicas de caminho definidas no assetlinks.json para o Android 15 e versões mais recentes.

Para evitar que o app processe todos os links de um domínio no Android 14 e versões anteriores quando você pretende usar links dinâmicos de apps para caminhos mais específicos no Android 15 e versões mais recentes, inclua um caminho não correspondente no filtro de intent do manifesto. Adicione um elemento <data> com um atributo android:path que provavelmente nunca será um caminho válido para seus links. Isso garante que o filtro de intent não corresponda a todos os caminhos em versões anteriores.

Exemplo:

<activity
    android:name=".MainActivity"
    android:exported="true"
    ...>
    <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="http" />
        <data android:scheme="https" />
        <data android:host="www.example.com" />

        <!-- Add a non-matching path for backward compatibility -->
        <data android:path="/no_match_for_older_android_versions" />

        <uri-relative-filter-group android:allow="true">
          <data android:pathPattern="/.*"/>
        </uri-relative-filter-group>
    </intent-filter>
</activity>

Ao adicionar <data android:path="/no_match_for_older_android_versions" />, você garante que, no Android 14 e versões anteriores, esse filtro de intent não corresponda a nenhum link recebido, mas ainda permite que o domínio seja verificado para uso com links dinâmicos de apps no Android 15 e versões mais recentes com base nas regras de correspondência avançadas nas regras de assetlinks.json.

Se você já tiver links de apps com regras de caminho específicas (como android:pathPrefix) no manifesto e quiser começar a usar links dinâmicos de apps no Android 15 e versões mais recentes, adicione o elemento <uri-relative-filter-group> diretamente aos filtros de intent atuais.

Como o Android 14 e versões anteriores ignoram o elemento <uri-relative-filter-group>, os links do app atuais continuam funcionando exatamente como agora em dispositivos com versões anteriores do Android.

No entanto, é preciso considerar cuidadosamente como o Android 15 e versões mais recentes avaliam a configuração "mista":

  • Filtragem de duas camadas:no Android 15 e versões mais recentes, o sistema avalia os filtros de intent como uma união. Um URL passa na verificação de manifesto se atender às tags <data> estáticas legadas ou às regras gerais no <uri-relative-filter-group>. Depois que o URL passa por essa verificação inicial do manifesto, o sistema aplica as regras dinâmicas definidas no arquivo assetlinks.json como uma segunda camada de filtragem detalhada. Isso significa que as regras JSON do lado do servidor determinam quais desses URLs correspondentes realmente abrem o app.

Exemplo de configuração híbrida:

<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" />
    <data android:host="www.example.com" />

    <!-- Legacy rule: Android 14 and lower use this. Android 15 and higher
         also use this. -->
    <data android:pathPrefix="/store" />

    <!--
      Dynamic rule: Android 14 and lower ignore this. Android 15 and higher
      evaluate this as a union between all paths and the configuration
      specified in the assetlinks.json file. Make sure to apply further
      refinements in the assetlinks.json file to prevent all URL paths from
      opening in the app.
    -->
    <uri-relative-filter-group android:allow="true">
        <data android:pathPrefix="/" />
    </uri-relative-filter-group>
</intent-filter>