The Android Developer Challenge is back! Submit your idea before December 2.

Verificar Android App Links

Android App Links são um tipo especial de link direto que permite que os URLs do seu site abram o conteúdo correspondente de imediato no app para Android (sem exigir que o usuário selecione o app).

Para adicionar Android App Links ao seu app, defina filtros de intent que abram o conteúdo do app usando URLs HTTP (conforme descrito em Criar links diretos para conteúdo de app) e verifique se você possui os URLs do app e do site (conforme descrito neste guia). Se o sistema verificar que você possui os URLs, ele encaminhará automaticamente esses intents de URL para o app.

Para verificar a propriedade do app e do site, as etapas a seguir são obrigatórias:

  • Solicite a verificação automática do link de app no seu manifesto. Isso indica para o sistema Android que é preciso verificar se o app pertence ao domínio de URL usado nos filtros de intent.
  • Declare o relacionamento entre o site e os filtros de intent hospedando um arquivo JSON de Digital Asset Links no seguinte local:
    https://domain.name/.well-known/assetlinks.json
    .

É possível encontrar informações relacionadas nos seguintes recursos:

  • Adicionar Android App Links
  • Criar uma lista de instruções
  • A diferença entre links diretos e links de app

    Um link direto é um filtro de intent que permite que os usuários insiram diretamente uma atividade específica no seu app para Android. A ação de clicar em um desses links pode abrir uma caixa de diálogo de desambiguação, permitindo ao usuário selecionar um de vários apps (inclusive o seu) que podem processar o URL especificado. Por exemplo, a figura 1 mostra a caixa de diálogo de desambiguação depois que o usuário clica em um link de mapa, perguntando se ele quer abrir o link no Maps ou no Chrome.

    Figura 1. Caixa de diálogo de desambiguação.

    Um Android App Link é um link direto baseado no URL do site que foi verificado como pertencente ao seu site. Por isso, a ação de clicar em um deles abre o app de imediato (se estiver instalado). A caixa de diálogo de desambiguação não é exibida. Mas, posteriormente, o usuário pode mudar a preferência para o modo de processar esses links.

    A tabela a seguir descreve diferenças mais específicas.

    Links diretosLinks do app
    Esquema do URL de intent http, https ou um esquema personalizado Requer http ou https
    Ação do intent Qualquer ação Requer android.intent.action.VIEW
    Categoria de intent Qualquer categoria Requer android.intent.category.BROWSABLE e android.intent.category.DEFAULT
    Verificação de link Nenhum Requer um arquivo Digital Asset Links exibido no seu site com HTTPS
    Experiência do usuário Pode mostrar uma caixa de diálogo de desambiguação para o usuário selecionar qual app abrirá o link Nenhuma caixa de diálogo. O app é aberto para processar os links do seu site
    Compatibilidade Todas as versões do Android Android 6.0 e posterior

    Solicitar verificação de links de app

    Para ativar a verificação do processamento de links para seu app, defina android:autoVerify="true" em qualquer filtro de intent de URL da Web no manifesto do app que inclui a ação de intent android.intent.action.VIEW e a categoria de intent android.intent.category.BROWSABLE, conforme mostrado no seguinte snippet de código do manifesto:

        <activity ...>
    
            <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" android:host="www.example.com" />
                <data android:scheme="https" />
            </intent-filter>
    
        </activity>
        

    Quando android:autoVerify="true" estiver presente em qualquer um dos filtros de intent, a instalação do app em dispositivos com o Android 6.0 e posterior fará com que o sistema tente verificar todos os hosts associados aos URLs em qualquer um dos filtros de intent do app. A verificação envolve o seguinte:

    1. O sistema inspeciona todos os filtros de intent que incluem:
      • Ação: android.intent.action.VIEW
      • Categorias: android.intent.category.BROWSABLE e android.intent.category.DEFAULT
      • Esquema de dados: http ou https
    2. Para cada nome de host exclusivo encontrado nos filtros de intent acima, o Android consulta os sites correspondentes para o arquivo Digital Asset Links em https://hostname/.well-known/assetlinks.json.

    O sistema só estabelecerá seu app como o gerenciador tradicional para os padrões de URL especificados se encontrar um arquivo Digital Asset Links correspondente para todos os hosts no manifesto.

    Oferecer compatibilidade com links de app para diversos hosts

    O sistema precisa verificar cada host especificado nos elementos de dados dos filtros de intent de URL do app com relação aos arquivos Digital Asset Links hospedados em todos os respectivos domínios da Web. Se alguma verificação falhar, o app não será considerado gerenciador tradicional para nenhum padrão de URL definido nos próprios filtros de intent. Nesse caso, o sistema usará o próprio comportamento padrão para resolver o intent, conforme descrito em Criar links diretos para conteúdo de app.

    Por exemplo, um app com os seguintes filtros de intent falharia na verificação se um arquivo assetlinks.json não fosse encontrado em https://www.example.com/.well-known/assetlinks.json e 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" android:host="www.example.com" />
              <data android:scheme="https" />
            </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" android:host="www.example.net" />
            </intent-filter>
          </activity>
    
        </application>
        

    Lembre-se de que todos os elementos <data> no mesmo filtro de intent são mesclados para considerar todas as variações dos atributos combinados. Por exemplo, o primeiro filtro de intent acima inclui um elemento <data> que declara apenas o esquema HTTPS. Mas, ele é combinado com o outro elemento <data> para que o filtro de intent seja compatível com http://www.example.com e https://www.example.com. Dessa forma, será preciso criar filtros de intent separados quando você quiser definir combinações específicas de esquemas e domínios de URI.

    Oferecer compatibilidade com links de app para diversos 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. Por isso, é preciso publicar um assetlinks.json válido em https://www.example.com/.well-known/assetlinks.json e em 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" android:host="www.example.com" />
              <data android:scheme="https" 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), precisará publicar seu arquivo assetlinks.json no nome do host raiz (example.com). Por exemplo, um app com o seguinte filtro de intent terá a verificação aprovada para 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" android:host="*.example.com" />
            </intent-filter>
          </activity>
        </application>
        

    Declarar associações de site

    É preciso publicar um arquivo JSON Digital Asset Links no seu site para indicar os apps para Android associados ao site e verificar os intents de URL do app. O arquivo JSON usa os seguintes campos para identificar aplicativos associados:

    • package_name: o ID do aplicativo declarado no arquivo build.gradle do app.
    • sha256_cert_fingerprints: as impressões digitais SHA256 do certificado de assinatura do seu app. É possível usar o Java Keytool para gerar a impressão digital usando o seguinte comando:
          $ keytool -list -v -keystore my-release-key.keystore
          
      Esse campo é compatível com diversas impressões digitais, que podem ser usadas para fins de compatibilidade com diferentes versões do seu app, como versões de depuração e de produção.

    O seguinte arquivo assetlinks.json de exemplo concede direitos de abertura de link a um app para Android com.example:

        [{
          "relation": ["delegate_permission/common.handle_all_urls"],
          "target": {
            "namespace": "android_app",
            "package_name": "com.example",
            "sha256_cert_fingerprints":
            ["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"]
          }
        }]
        

    Associar um site com diversos apps

    Um site pode declarar associações com vários apps no mesmo arquivo assetlinks.json. A lista de arquivos a seguir mostra um exemplo de arquivo de instrução que declara associação com dois apps, separadamente, e reside em https://www.example.com/.well-known/assetlinks.json:

        [{
          "relation": ["delegate_permission/common.handle_all_urls"],
          "target": {
            "namespace": "android_app",
            "package_name": "com.example.puppies.app",
            "sha256_cert_fingerprints":
            ["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"]
          }
          },
          {
          "relation": ["delegate_permission/common.handle_all_urls"],
          "target": {
            "namespace": "android_app",
            "package_name": "com.example.monkeys.app",
            "sha256_cert_fingerprints":
            ["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"]
          }
        }]
        

    Diferentes apps podem processar links para recursos distintos sob o mesmo host da Web. Por exemplo, o app1 pode declarar um filtro de intent para https://example.com/articles, e o app2 pode declarar um filtro de intent para https://example.com/videos.

    Observação: diversos apps associados a um domínio podem ser assinados com o mesmo certificado ou com certificados diferentes.

    Associar diversos sites a um único app

    Diversos sites podem declarar associações ao mesmo app nos respectivos arquivos assetlinks.json. As listas de arquivos a seguir mostram um exemplo de como declarar a associação de example.com e example.net com o app1. A primeira lista mostra a associação de example.com ao app1:

    https://www.example.com/.well-known/assetlinks.json

        [{
          "relation": ["delegate_permission/common.handle_all_urls"],
          "target": {
            "namespace": "android_app",
            "package_name": "com.mycompany.app1",
            "sha256_cert_fingerprints":
            ["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"]
          }
        }]
        

    A próxima lista mostra a associação de example.net ao app1. Somente o local onde esses arquivos são hospedados é diferente (.com e .net):

    https://www.example.net/.well-known/assetlinks.json

        [{
          "relation": ["delegate_permission/common.handle_all_urls"],
          "target": {
            "namespace": "android_app",
            "package_name": "com.mycompany.app1",
            "sha256_cert_fingerprints":
            ["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"]
          }
        }]
        

    Publicar o arquivo de verificação JSON

    É preciso publicar o arquivo de verificação JSON no seguinte local:

    https://domain.name/.well-known/assetlinks.json

    As condições a seguir precisam ser atendidas:

    • O arquivo assetlinks.json é exibido com o tipo de conteúdo application/json.
    • O arquivo assetlinks.json precisa ser compatível com acesso por conexão HTTPS, mesmo que os filtros de intent do seu app declarem HTTPS como o esquema de dados.
    • O arquivo assetlinks.json precisa ser compatível com acesso sem redirecionamentos (301 ou 302) e com acesso por bots (seu robots.txt precisa permitir o rastreamento de /.well-known/assetlinks.json).
    • Se os links do app forem compatíveis com vários domínios de host, será necessário publicar o arquivo assetlinks.json em cada domínio. Consulte Oferecer compatibilidade com links de app para diversos hosts.
    • Não publique seu app com URLs de desenvolvimento/teste em arquivos de manifesto que podem não ser publicamente acessíveis (por exemplo, todos aqueles que só podem ser acessados com uma VPN). Uma solução alternativa nesses casos é configurar variantes de compilação para gerar outro arquivo de manifesto para versões de desenvolvimento.

    Testar links de app

    Ao implementar o recurso de vinculação do app, teste essa funcionalidade para verificar se o sistema consegue associar seu app aos sites e processar solicitações de URL conforme esperado.

    Para testar um arquivo de instrução existente, use a ferramenta Statement List Generator and Tester.

    Confirmar a lista de hosts a serem verificados

    Ao realizar testes, confirme a lista de hosts associados que o sistema deve verificar para seu app. Faça uma lista de todos os URLs cujos filtros de intent correspondentes incluem os seguintes atributos e elementos:

    • Atributo android:scheme com um valor http ou https
    • Atributo android:host com um padrão de URL de domínio
    • Elemento da categoria android.intent.action.VIEW
    • Elemento da categoria android.intent.category.BROWSABLE

    Use essa lista para verificar se um arquivo JSON Digital Asset Links foi disponibilizado para cada host e subdomínio nomeados.

    Confirmar os arquivos Digital Asset Links

    Para cada site, use a API Digital Asset Links para confirmar que o arquivo JSON Digital Asset Links está hospedado e definido corretamente:

        https://digitalassetlinks.googleapis.com/v1/statements:list?
           source.web.site=https://domain.name:optional_port&
           relation=delegate_permission/common.handle_all_urls
        

    Testar um intent de URL

    Depois de confirmar a lista de sites a serem associados ao app e que o arquivo JSON hospedado é válido, instale o app no seu dispositivo. Aguarde pelo menos 20 segundos para que o processo de verificação assíncrona seja concluído. Use o seguinte comando para saber se o sistema verificou o app e definir as políticas corretas de processamento de links:

        adb shell am start -a android.intent.action.VIEW \
            -c android.intent.category.BROWSABLE \
            -d "http://domain.name:optional_port"
        

    Como parte do processo de testes, é possível verificar as definições atuais do sistema para o processamento de links. Use o comando a seguir para ver uma lista das políticas de processamento de links existentes para todos os apps no dispositivo conectado:

        adb shell dumpsys package domain-preferred-apps
        

    Ou o comando abaixo, que tem o mesmo efeito:

        adb shell dumpsys package d
        

    Observação: aguarde pelo menos 20 segundos depois da instalação do app para que o sistema conclua o processo de verificação.

    O comando retorna uma lista de cada usuário ou perfil definido no dispositivo, precedida por um cabeçalho no seguinte formato:

        App linkages for user 0:
        

    Depois desse cabeçalho, o resultado usa o formato a seguir para listar as configurações de processamento de links para esse usuário:

        Package: com.android.vending
        Domains: play.google.com market.android.com
        Status: always : 200000002
        

    A lista indica quais apps foram associados a cada domínio para o usuário:

    • Package: identifica um app pelo nome do pacote, como declarado no manifesto.
    • Domains: mostra a lista completa de hosts cujos links da Web são processados pelo app, usando espaços em branco como delimitadores.
    • Status: mostra a configuração atual de processamento de links para esse app. Um app aprovado na verificação e cujo manifesto contém android:autoVerify="true" mostra o status always. O número hexadecimal depois desse status está relacionado ao registro do sistema Android das preferências de vinculação de app do usuário. Esse valor não indica se a verificação foi concluída.

    Observação: se o usuário alterar as configurações de vinculação de app antes de concluir a verificação, poderá ver um falso positivo de verificação bem-sucedida, mesmo que ela tenha falhado. No entanto, a falha dessa verificação não fará diferença se o usuário tiver ativado o app de maneira explícita para abrir links compatíveis sem perguntar. Isso acontece porque as preferências do usuário têm precedência sobre a verificação programática (ou a falta dela). Como resultado, o link acessa diretamente o app, sem mostrar caixas de diálogo, como se a verificação tivesse sido bem-sucedida.

    Exemplo de teste

    Para que a verificação de vinculação de app seja realizada corretamente, o sistema precisa verificar seu app com todos os sites especificados por você nos filtros de intent e atender aos critérios de vinculação de app. O exemplo abaixo mostra uma configuração de manifesto com diversos links de aplicativo definidos:

        <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>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="https" android:host="www.example2.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" android:host="account.example.com" />
                </intent-filter>
            </activity>
    
              <activity android:name=”ThirdActivity”>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:scheme="https" android:host="map.example.com" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="market" android:host="example.com" />
                </intent-filter>
              </activity>
    
        </application>
        

    A lista de hosts que a plataforma tentaria verificar do manifesto acima é:

        www.example.com
        mobile.example.com
        www.example2.com
        account.example.com
        

    A lista de hosts que a plataforma não tentaria verificar do manifesto acima é:

        map.example.com (it does not have android.intent.category.BROWSABLE)
        market://example.com (it does not have either an “http” or “https” scheme)
        

    Para saber mais sobre listas de instruções, consulte Criar uma lista de instruções.