Resolução de intents da Web

Com o Android 12, intents da Web genéricas são resolvida como uma atividade no app apenas se ele for aprovado para o domínio específico contido na intent. Se o app não for aprovado para o domínio, a intent da Web será resolvida no app de navegação padrão do usuário.

Os apps podem receber essa aprovação de uma das seguintes maneiras:

Se o app invocar intents da Web, considere adicionar uma solicitação ou uma caixa de diálogo que peça ao usuário para confirmar a ação.

Atributos de intents da Web

Uma intent da Web é uma intent que contém as características a seguir:

Os filtros de intents da Web precisam incluir a categoria navegável

A partir do Android 12, os filtros de intent da Web também precisam declarar a categoria CATEGORY_BROWSABLE para que uma intent específica da Web seja resolvida como uma atividade no app.

O recurso Links do app Android, disponível no Android 8.0 (nível 26 da API) e versões mais recentes, usa a API Digital Asset Links para associar um app específico a um domínio da Web. Essa associação permite ao sistema confiar que o app foi aprovado pelo site para abrir automaticamente links desse domínio.

A partir do Android 12, é possível invocar manualmente a verificação de domínio para avaliar como o sistema resolve Links do app Android.

Em apps direcionados ao Android 12, o sistema faz várias mudanças na forma como os Links do app Android são verificados. Essas mudanças melhoram a confiabilidade da experiência de vinculação de apps e oferecem mais controle para os desenvolvedores e usuários finais. É possível invocar manualmente a verificação de domínio para testar a confiabilidade das declarações.

Se o app é destinado ao Android 12 e depende da verificação de Links do app Android para abrir links da Web no app, atualize as declarações de Links do app Android para oferecer compatibilidade com o processo de verificação mudado.

Atualizar as declarações de Links do app Android

O processo de verificação de domínio exige uma conexão com a Internet e pode levar algum tempo para ser concluído. Para ajudar a melhorar a eficiência do processo, o sistema verifica um domínio para um app direcionado ao Android 12 apenas se esse domínio estiver em um elemento <intent-filter> especificamente formatado. O elemento <intent-filter> precisa conter as ações, categorias e esquemas exibidos no snippet a seguir:

<!-- 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.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <data android:scheme="http" />
    <data android:scheme="https" />

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

Invocar manualmente a verificação de domínio

A partir do Android 12, é possível invocar manualmente a verificação de domínio para um app instalado em um dispositivo. É possível realizar esse processo sendo o app direcionado ao Android 12 ou não.

Estabelecer uma conexão com a Internet

Para realizar a verificação de domínio, o dispositivo de teste precisa estar conectado à Internet.

Oferecer compatibilidade com o processo de verificação de domínio atualizado

Se o app for direcionado ao Android 12, o sistema usará o processo de verificação de domínio atualizado automaticamente.

Caso contrário, é possível ativar manualmente o processo de verificação atualizado. Para fazer isso, execute os comandos a seguir em uma janela de terminal:

adb shell am compat enable 175408749 PACKAGE_NAME

Redefinir o estado de Links do app Android em um dispositivo

Antes de invocar manualmente a verificação de domínio em um dispositivo, você precisa redefinir o estado de Links do app Android no dispositivo de teste. Para fazer isso, execute os comandos a seguir em uma janela de terminal:

adb shell pm set-app-links --package PACKAGE_NAME 0 all

Esse comando coloca o dispositivo no mesmo estado em que estava antes do usuário escolher apps padrão para qualquer domínio.

Invocar o processo de verificação do domínio

Depois de redefinir o estado de Links do app Android em um dispositivo, você poderá fazer a verificação por conta própria. Para fazer isso, execute os comandos a seguir em uma janela de terminal:

adb shell pm verify-app-links --re-verify PACKAGE_NAME

Analisar os resultados da verificação

Após aguardar um tempo para que o agente de verificação conclua as solicitações, analise os resultados. Para isso, execute o comando a seguir:

adb shell pm get-app-links PACKAGE_NAME

A saída deste comando será parecida com esta:

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

Os domínios aprovados na verificação têm um estado de verificação de domínio verified (verificado). Qualquer outro estado indica que não foi possível realizar a verificação de domínio. Especificamente, o estado none (nenhum) indica que talvez o agente de verificação ainda não tenha concluído o processo.

A lista a seguir mostra os possíveis valores que a verificação pode retornar para um domínio:

none
Nada foi registrado para este domínio. Aguarde mais alguns minutos para que o agente de verificação conclua as solicitações relacionadas à verificação de domínio e invoque o processo de verificação de domínio novamente.
verified
O domínio foi verificado para o app de declaração.
approved
O domínio foi aprovado de maneira forçada, geralmente pela execução de um comando do shell.
denied
O domínio foi negado de maneira forçada, geralmente pela execução de um comando do shell.
migrated
O sistema manteve o resultado de um processo anterior que usava a verificação de domínio legada.
restored
O domínio foi aprovado após a restauração de dados do usuário. Presume-se que o domínio foi verificado anteriormente.
legacy_failure
O domínio foi rejeitado por um verificador legado. O motivo específico da falha é desconhecido.
system_configured
O domínio foi aprovado automaticamente pelo configurador do dispositivo.
Código de erro de 1024 ou maior.

Código de erro personalizado específico do verificador do dispositivo.

Confira se você estabeleceu uma conexão de rede e invoque o processo de verificação de domínio novamente.

Solicitar ao usuário para associar o app a um domínio

Outra maneira de aprovar o app para um domínio é pedir ao usuário para associá-lo a esse domínio.

Conferir se o app já foi aprovado para o domínio

Antes de solicitar ao usuário, confira se o app é o gerenciador padrão dos domínios definidos nos elementos <intent-filter>. Consulte o estado da aprovação usando um dos métodos a seguir:

DomainVerificationManager

O snippet de código a seguir demonstra como usar a API DomainVerificationManager:

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState.hostToStateMap
    .filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState.hostToStateMap
    .filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState.hostToStateMap
    .filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

Java

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

Programa de linha de comando

Quando testar o app durante o desenvolvimento, você pode executar o comando a seguir para consultar o estado da verificação dos domínios da sua organização:

adb shell pm get-app-links --user cur PACKAGE_NAME

Na saída de exemplo a seguir, mesmo que o app tenha falhado na verificação para o domínio "example.org", o usuário 0 aprovou manualmente o app nas configurações do sistema e nenhum outro pacote foi verificado para esse domínio.

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

Fornecer contexto para a solicitação

Antes de fazer essa solicitação de aprovação de domínio, forneça um contexto para o usuário. Por exemplo, você pode mostrar uma tela de apresentação, uma caixa de diálogo ou um elemento de IU parecido que explique ao usuário por que o app precisa ser o gerenciador padrão de um determinado domínio.

Fazer a solicitação

Após o usuário entender o que o app está pedindo, faça a solicitação. Para fazer isso, invoque uma intent que inclua a ação da intenet ACTION_APP_OPEN_BY_DEFAULT_SETTINGS e uma string de dados correspondente a package:com.example.pkg para o app de destino, conforme mostrado no snippet de código a seguir:

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

Java

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package: " + context.getPackageName()));
context.startActivity(intent);

Quando a intent for invocada, os usuários verão uma tela de configurações chamada Abrir por padrão. Essa tela contém um botão de opção Abrir links compatíveis, conforme mostrado na figura 1.

Quando o usuário ativar a opção Abrir links compatíveis, um conjunto de caixas de seleção será exibido em uma seção chamada Links para abrir neste app. Em seguida, os usuários poderão selecionar os domínios que querem associar ao app. Também é possível selecionar Adicionar link para incluir domínios, conforme mostrado na Figura 2. Mais tarde, quando os usuários selecionarem um link nos domínios adicionados, ele será aberto automaticamente no app.

Quando o botão de opção estiver ativado, uma seção perto da parte inferior
    incluirá caixas de seleção e um botão &quot;Adicionar link&quot;
Figura 1. Tela de configurações do sistema em que os usuários podem escolher quais links são abertos no app por padrão.
Cada caixa de seleção representa um domínio que você pode adicionar. Os
    botões da caixa de diálogo são &quot;Cancelar&quot; e &quot;Adicionar&quot;.
Figura 2. Caixa de diálogo em que os usuários podem escolher outros domínios para associar ao app.

Alternar a aprovação do domínio manualmente

A verificação de domínio e a seleção de usuário podem ser alternadas com comandos do shell que permitem ao desenvolvedor definir manualmente o estado adequado para depuração, execução de testes ou para casos específicos, por exemplo, quando não há conexão com a Internet.

Uma explicação completa desses comandos está disponível na saída do adb shell pm.

Todas as restrições de aprovação única e da mesma precedência verificadas são aplicadas, mesmo quando aprovadas usando os comandos do shell. Assim, em alguns casos especiais, como na instalação de duas variantes do app, é necessário um processamento especial para abrir um link da Web no app esperado.

Verificar vários apps

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, exiba uma caixa de diálogo de seletor personalizada que contenha os resultados da chamada de queryIntentActivities(). O usuário poderá selecionar o app preferido na lista de apps correspondentes exibidos na caixa de diálogo.

Domínios abertos no app que não podem ser verificados por ele

A função principal do app pode ser a de abrir links como um terceiro, sem a capacidade de verificar os domínios processados. Se esse for o caso, explique aos usuários que, ao selecionar um link da Web, eles não poderão escolher entre um app primário e seu app (de terceiros). Os usuários precisam associar manualmente os domínios ao app de terceiros.

Além disso, considere apresentar uma caixa de diálogo ou atividade trampolim, que possibilite que o usuário abra o link no app primário, se ele preferir, agindo como um proxy. Antes de configurar essa atividade de caixa de diálogo ou trampolim, configure seu app para que ele tenha a visibilidade de pacote nos apps primários correspondentes ao filtro de intent da Web do app.