Links de aplicativo Android

Muitas vezes, é desejável conectar um site e um aplicativo móvel para que os links em um site iniciem o aplicativo móvel e exibam conteúdo no aplicativo móvel. A vinculação de aplicativo, que também é conhecida como vinculação profunda, é uma técnica que permite que um dispositivo móvel responda a um URI e inicie conteúdo em um aplicativo móvel representado pelo URI.

O Android lida com links de aplicativos por meio do sistema de intenção. Quando você toca em um link em um navegador móvel, o navegador envia uma intenção que o Android delegará a um aplicativo registrado. Esses links podem ser baseados em um esquema personalizado, como myappname://, ou podem usar o esquema HTTP ou HTTPS. Por exemplo, clicar em um link em um site de receitas abriria um aplicativo móvel associado a esse site e, em seguida, exibiria uma receita específica para o usuário. Se houver mais de um aplicativo registrado para lidar com a intenção, o Android exibirá uma caixa de diálogo de desambiguação que perguntará ao usuário qual aplicativo selecionar para lidar com a intenção. Os usuários que não têm seu aplicativo instalado são levados para o conteúdo em seu site.

O Android classifica os links de aplicativos em três categorias:

  • Links profundos são URIs de qualquer esquema que levam os usuários a conteúdo específico em seu aplicativo. Quando um link profundo é clicado, uma caixa de diálogo de desambiguação pode aparecer solicitando que o usuário selecione um aplicativo para lidar com o link profundo.
  • Links da Web são links profundos que usam o esquema HTTP ou HTTPS. No Android 12 e superior, um link da Web sempre mostra o conteúdo em um navegador da Web. Em versões anteriores do Android, se um aplicativo puder manipular o link da Web, será exibida uma caixa de diálogo de desambiguação solicitando que o usuário selecione um aplicativo para lidar com o link da Web.
  • Os links de aplicativos Android, que estão disponíveis na API 23+, são links da Web que usam o esquema HTTP ou HTTPS e contêm o atributo autoVerify. Esse atributo permite que seu aplicativo se torne o manipulador padrão de um link de aplicativo. Portanto, quando um link de aplicativo é clicado, seu aplicativo é aberto sem exibir uma caixa de diálogo de desambiguação.

Os aplicativos Android .NET MAUI podem oferecer suporte a todas as três categorias de links de aplicativos. No entanto, este artigo se concentra em links de aplicativos Android. Isso requer comprovar a propriedade de um domínio, bem como hospedar um arquivo JSON de arquivos de links de ativos digitais no domínio, que descreve a relação com o seu aplicativo. Isso permite que o Android verifique se o aplicativo que está tentando manipular um URI tem a propriedade do domínio dos URIs para impedir que aplicativos mal-intencionados interceptem seus links de aplicativo.

O processo para manipular links de aplicativos Android em um aplicativo Android do .NET MAUI é o seguinte:

  1. Verifique a propriedade do domínio. Para obter mais informações, consulte Verificar a propriedade do domínio.
  2. Crie e hospede um arquivo de links de ativos digitais em seu site. Para obter mais informações, consulte Criar e hospedar um arquivo de links de ativos digitais.
  3. Configure um filtro de intenção em seu aplicativo para os URIs do site. Para obter mais informações, consulte Configurar o filtro de intenção.
  4. Leia os dados da intenção de entrada. Para obter mais informações, consulte Ler os dados da intenção de entrada.

Importante

Para usar links de aplicativos Android:

  • Uma versão do seu aplicativo precisa estar ativa no Google Play.
  • Um site complementar precisa ser registrado no aplicativo no Console do Desenvolvedor do Google. Depois que o aplicativo estiver associado a um site, poderão ser indexados URIs que funcionem tanto para o site quanto para o aplicativo, que podem ser atendidos nos resultados da pesquisa. Para obter mais informações, consulte Indexação de Aplicativos no Google Search em support.google.com.

Para obter mais informações sobre links de aplicativos Android, consulte Manipulando links de aplicativos Android.

Verificar a propriedade de domínio

Você precisará verificar sua propriedade do domínio do qual está veiculando links de aplicativo no Google Search Console. A verificação de propriedade significa provar que você possui um site específico. O Google Search Console dá suporte a várias abordagens de verificação. Para obter mais informações, consulte Verificar a propriedade do site em support.google.com.

Os links de aplicativos Android exigem que o Android verifique a associação entre o aplicativo e o site antes de definir o aplicativo como o manipulador padrão para o URI. Essa verificação ocorrerá quando o aplicativo for instalado pela primeira vez. O arquivo de links de ativos digitais é um arquivo JSON que precia ser hospedado pelo domínio da Web relevante no seguinte local: https://domain.name/.well-known/assetlinks.json.

O arquivo de ativo digital contém os metadados necessários para que o Android verifique a associação. O arquivo exige os seguintes pares chave-valor:

  • namespace – o namespace do aplicativo Android.
  • package_name – o nome do pacote do aplicativo Android.
  • sha256_cert_fingerprints – as impressões digitais SHA256 do aplicativo assinado, obtidas do seu arquivo .keystore. Para obter informações sobre como localizar a assinatura do repositório de chaves, consulte Localizar a assinatura do repositório de chaves.

O arquivo de exemplo assetlinks.json a seguir concede direitos de abertura de link a um aplicativo Android com.companyname.myrecipeapp:

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

É possível registrar mais de uma impressão digital SHA256 para dar suporte a diferentes versões ou builds do seu aplicativo. O seguinte arquivo assetlinks.json concede direitos de abertura de link aos aplicativos Android com.companyname.myrecipeapp e com.companyname.mycookingapp:

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

Dica

Use a ferramenta Gerador e testador de lista de instruções para ajudar a gerar o JSON correto e validá-lo.

Ao publicar seu arquivo de verificação JSON em https://domain.name/.well-known/assetlinks.json, você precisa garantir que:

  • O arquivo é servido com o tipo de conteúdo application/json.
  • O arquivo precisa ser acessível por HTTPS, independentemente de seu aplicativo usar ou não HTTPS como esquema.
  • O arquivo precisa ser acessível sem redirecionamentos.
  • Se os links do aplicativo oferecerem suporte a vários domínios, você precisará publicar o arquivo assetlinks.json em cada domínio.

Você pode confirmar se o arquivo de ativos digitais está formatado e hospedado corretamente usando a API de links de ativos digitais do Google:

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=
  https://<WEB SITE ADDRESS>:&relation=delegate_permission/common.handle_all_urls

Para obter mais informações, consulte Declarar associações de site em developer.android.com.

Configurar o filtro de intenção

É preciso configurar um filtro de intenção que mapeie um URI, ou conjunto de URIs, de um site para uma atividade em seu aplicativo Android. No .NET MAUI, isso pode ser obtido adicionando o IntentFilterAttribute à sua atividade. O filtro de intenção precisa declarar as seguintes informações:

  • ActionView – isso registrará o filtro de intenção para responder a solicitações de visualização de informações.
  • Categories – o filtro de intenção deve registrar ambos CategoryDefault e CategoryBrowsable para ser capaz de lidar corretamente com o URI da Web.
  • DataScheme – o filtro de intenção precisa declarar um esquema personalizado e/ou HTTPS.
  • DataHost – este é o domínio do qual os URIs se originarão.
  • DataPathPrefix – este é um caminho opcional para recursos no site, que deve começar com um /.
  • AutoVerify – isso diz ao Android para verificar a relação entre o aplicativo e o site. Ele precisa ser definido como true, caso contrário, o Android não verificará a associação entre o aplicativo e o site e, portanto, não definirá seu aplicativo como o manipulador padrão de um URI.

O exemplo a seguir mostra como usar o IntentFilterAttribute para manipular links de https://www.recipe-app.com/recipes:

using Android.App;
using Android.Content;
using Android.Content.PM;

namespace MyNamespace;

[Activity(
    Theme = "@style/Maui.SplashTheme",
    MainLauncher = true,
    ConfigurationChanges = ConfigChanges.ScreenSize |
        ConfigChanges.Orientation |
        ConfigChanges.UiMode |
        ConfigChanges.ScreenLayout |
        ConfigChanges.SmallestScreenSize |
        ConfigChanges.KeyboardHidden |
        ConfigChanges.Density)]
[IntentFilter(
    new string[] { Intent.ActionView },
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
    DataScheme = "https",
    DataHost = "recipe-app.com",
    DataPath = "/recipe",
    AutoVerify = true,)]    
public class MainActivity : MauiAppCompatActivity
{
}

Observação

Vários esquemas e hosts podem ser especificados em seu filtro de intenção. Para obter mais informações, consulte Criar links profundos para conteúdo de aplicativo em developer.android.com.

O Android verificará cada host identificado nos filtros de intenção em relação ao arquivo de ativos digitais no site, antes de registrar o aplicativo como o manipulador padrão de um URI. Todos os filtros de intenção precisam passar pela verificação antes que o Android possa estabelecer o aplicativo como o manipulador padrão. Depois de adicionar um filtro de intenção com um URI para conteúdo de atividade, o Android poderá rotear qualquer intenção que tenha URIs correspondentes para seu aplicativo em runtime.

Também pode ser necessário marcar sua atividade como exportável, para que sua atividade possa ser iniciada por outros aplicativos. Isso pode ser alcançado adicionando Exported = true ao ActivityAttribute existente. Para obter mais informações, consulte Elemento de atividade em developer.android.com.

Quando uma intenção de URI da Web é invocada, o Android tenta as seguintes ações até que a solicitação seja bem-sucedida:

  1. Abre o aplicativo preferencial para manipular o URI.
  2. Abre o único aplicativo disponível para manipular o URI.
  3. Permite que o usuário selecione um aplicativo para manipular o URI.

Para obter mais informações sobre intenções e filtros de intenção, consulte Intenções e filtros de intenção em developer.android.com.

Ler os dados da intenção de entrada

Quando o Android inicia sua atividade por meio de um filtro de intenção, você pode usar os dados fornecidos pela intenção para determinar o que fazer. Isso deve ser realizado em um delegado de ciclo de vida inicial, idealmente OnCreate. O delegado OnCreate é chamado quando uma atividade é criada. Para obter mais informações sobre delegados de ciclo de vida, consulte Eventos do ciclo de vida da plataforma.

Para responder a um delegado de ciclo de vida do Android que está sendo chamado, chame o método ConfigureLifecycleEvents no objeto MauiAppBuilder no método CreateMauiapp de sua classe MauiProgram. Em seguida, no objeto ILifecycleBuilder, chame o método AddAndroid e especifique o Action que registra um manipulador para o delegado necessário:

using Microsoft.Maui.LifecycleEvents;
using Microsoft.Extensions.Logging;

namespace MyNamespace;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .ConfigureLifecycleEvents(lifecycle =>
            {
#if ANDROID
                lifecycle.AddAndroid(android =>
                {
                    android.OnCreate((activity, bundle) =>
                    {
                        var action = activity.Intent?.Action;
                        var data = activity.Intent?.Data?.ToString();

                        if (action == Android.Content.Intent.ActionView && data is not null)
                        {
                            activity.Finish();
                            Task.Run(() => HandleAppLink(data));
                        }
                    });
                });
#endif
            });

#if DEBUG
        builder.Logging.AddDebug();
#endif

        return builder.Build();
    }

    static void HandleAppLink(string url)
    {
        if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
            App.Current?.SendOnAppLinkRequestReceived(uri);
    }
}

A propriedade Intent.Action recupera a ação associada à intenção de entrada e a propriedade Intent.Data recupera os dados associados à intenção de entrada. Desde que a ação de intenção esteja definida como ActionView, os dados de intenção podem ser passados para sua classe App com o método SendOnAppLinkRequestReceived.

Aviso

Os links de aplicativo oferecem um vetor de ataque potencial em seu aplicativo, portanto, certifique-se de validar todos os parâmetros de URI e descartar quaisquer URIs malformados.

Em sua classe App, substitua o método OnAppLinkRequestReceived para receber e processar os dados de intenção:

namespace MyNamespace;

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();
    }

    protected override async void OnAppLinkRequestReceived(Uri uri)
    {
        base.OnAppLinkRequestReceived(uri);

        // Show an alert to test that the app link was received.
        await Dispatcher.DispatchAsync(async () =>
        {
            await Windows[0].Page!.DisplayAlert("App link received", uri.ToString(), "OK");
        });

        Console.WriteLine("App link: " + uri.ToString());
    }
}

No exemplo acima, a substituição OnAppLinkRequestReceived exibe o URI do link do aplicativo. Na prática, o link do aplicativo deve levar os usuários diretamente ao conteúdo representado pelo URI, sem solicitações, logins ou outras interrupções. Portanto, a substituição é o local a partir do qual invocar a navegação OnAppLinkRequestReceived para o conteúdo representado pelo URI.

Desde que o arquivo de ativo digital esteja hospedado corretamente, você pode usar o Android Debug Bridge, adb, com a ferramenta gerenciador de atividades, am, para simular a abertura de um URI a fim de garantir que os links do aplicativo funcionem corretamente. Por exemplo, o seguinte comando tenta exibir uma atividade de aplicativo de destino associada a um URI:

adb shell am start -W -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d YOUR_URI_HERE

Esse comando enviará uma intenção que o Android deve direcionar para seu aplicativo móvel, que deve iniciar e exibir a atividade registrada para o URI.

Observação

Você pode executar adb em um emulador ou um dispositivo.

Além disso, você pode exibir as políticas de manipulação de links existentes para os aplicativos instalados em um dispositivo:

adb shell dumpsys package domain-preferred-apps

Esse comando exibirá as seguintes informações:

  • Pacote – o nome do pacote do aplicativo.
  • Domínio – os domínios, separados por espaços, cujos links da Web serão manipulados pelo aplicativo.
  • Status – o status atual de manipulação de links do aplicativo. Um valor de always significa que o aplicativo definiu AutoVerify como true e passou na verificação do sistema. Ele é seguido por um número hexadecimal que representa o registro da preferência.

Para obter mais informações sobre o comando adb, consulte Android Debug Bridge.

Além disso, você pode gerenciar e verificar links de aplicativos Android por meio do Play Console. Para obter mais informações, consulte Gerenciar e verificar links de aplicativos Android em developer.android.com.

Para obter conselhos sobre solução de problemas, consulte Corrigir erros comuns de implementação em developer.android.com.