Adicionar filtros de intent para App Links

Os Links do app são links diretos que usam o esquema HTTP ou HTTPS e são verificados pelo Android como associados ao seu site. Para se registrar e processar App 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 do host na configuração assetlinks.json do seu site.
  3. Declare associações de site.

Confira a seguir 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 indica ao sistema que ele deve tentar verificar a associação entre o app e os esquemas e domínios especificados nas tags <data>. Recomendamos adicionar autoVerify="true" a cada filtro de intent que você quer verificar.
  • Elementos de dados: cada filtro de intent de App Links precisa incluir um ou mais elementos <data> que especificam os esquemas e formatos de host correspondentes ao seu 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 com seu 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 de host, o sistema (no Android 12 ou mais recente) vai tentar verificar cada um deles. Se algum host for verificado, o app se tornará o gerenciador padrão de links desse host. No Android 11 e em versões anteriores, a verificação falha se um host não puder ser verificado.

  • Vários filtros de intent: é importante criar filtros separados quando a 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 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 de forma estática no manifesto do app.

Por isso, recomendamos usar esta abordagem:

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

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

Oferecer suporte a links de app para vários hosts

O sistema precisa verificar o host especificado nos elementos de dados dos filtros de intent de URL do app com relação aos arquivos Digital Asset Links hospedados nos respectivos domínios da Web nesse filtro de intent. Se a verificação falhar, o sistema usará o próprio comportamento padrão para resolver o intent, conforme descrito em Criar links diretos para conteúdo de app. No entanto, o app ainda pode ser verificado como 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 seguintes filtros de intent passaria na verificação apenas 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>

Oferecer compatibilidade com links de app para vários subdomínios

O protocolo Digital Asset Links trata subdomínios nos seus filtros de intent como hosts exclusivos e separados. Portanto, se o filtro de intent listar vários hosts com subdomínios diferentes, será necessário 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 seguinte filtro de intent 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á apps conflitantes no dispositivo do usuário, contanto que você tenha a visibilidade de pacotes 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 aparecem na caixa de diálogo.

Os recursos de Dynamic App Link, incluindo regras avançadas de correspondência 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 os scheme e host declarados nos elementos <data> do manifesto para a verificação de links do app. 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 em versões anteriores, independente das regras específicas do caminho definidas no assetlinks.json para o Android 15 e versões mais recentes.

Para evitar que seu app processe todos os links de um domínio no Android 14 e versões anteriores quando você pretende usar os 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 de entrada, permitindo 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çada 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 em 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 do manifesto se satisfizer as tags <data> estáticas legadas ou as regras gerais no seu <uri-relative-filter-group>. Depois que o URL passa nessa verificação inicial do manifesto, o sistema aplica as regras dinâmicas definidas no arquivo assetlinks.json como uma segunda camada de filtragem refinada. Isso significa que as regras JSON do lado do servidor determinam quais desses URLs correspondentes abrem o app.

Exemplo de uma 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>