Criar um link direto para um destino

No Android, um link direto é aquele que leva você diretamente a um destino específico em um app.

O componente de navegação permite criar dois tipos diferentes de links diretos: explícito e implícito.

Criar um link direto explícito

Um link direto explícito é uma instância única de um link direto que usa um PendingIntent para direcionar os usuários a um local específico do app. Você pode exibir um link direto explícito como parte de uma notificação ou de um widget de app, por exemplo.

Quando um usuário abre o app por meio de um link direto explícito, a pilha de retorno da tarefa é limpa e substituída pelo destino do link direto. Ao aninhar gráficos, o destino inicial de cada nível de aninhamento, ou seja, o destino inicial de cada elemento <navigation> na hierarquia, também é adicionado à pilha. Isso significa que quando um usuário pressiona o botão "Voltar" em um destino de link direto, ele navega pela pilha de navegação como se tivesse entrado no app a partir do ponto de entrada.

Você pode usar a classe NavDeepLinkBuilder para construir um PendingIntent, como mostrado no exemplo abaixo. Se o contexto fornecido não for um Activity, o construtor usará PackageManager.getLaunchIntentForPackage() como a atividade padrão para iniciar, se disponível.

Kotlin

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .createPendingIntent()

Java

PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .createPendingIntent();

Por padrão, o NavDeepLinkBuilder inicia seu link direto explícito para o lançamento padrão da Activity declarada no manifesto do app. Se o NavHost estiver em outra atividade, especifique o nome do componente ao criar o builder de links diretos:

Kotlin

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .setComponentName(DestinationActivity::class.java)
    .createPendingIntent()

Java

PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
        .setGraph(R.navigation.nav_graph)
        .setDestination(R.id.android)
        .setArguments(args)
        .setComponentName(DestinationActivity.class)
        .createPendingIntent();

Se você tiver um ComponentName, poderá transmiti-lo diretamente para o builder:

Kotlin

val componentName = ...

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .setComponentName(componentName)
    .createPendingIntent()

Java

ComponentName componentName = ...;

PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
        .setGraph(R.navigation.nav_graph)
        .setDestination(R.id.android)
        .setArguments(args)
        .setComponentName(componentName)
        .createPendingIntent();

Se você já tiver um NavController, também será possível criar um link direto usando NavController.createDeepLink().

Criar um link direto implícito

Um link direto implícito é uma referência a um destino específico em um app. Quando o link direto é invocado, por exemplo, quando um usuário clica em um link, o Android pode abrir o app no destino correspondente.

Os links diretos podem ser correspondidos por URI, ações de intent e tipos MIME. É possível especificar vários tipos de correspondência para um único link direto, mas a correspondência de argumentos de URI é priorizada, seguida pela de ações e, em seguida, pela de tipos MIME.

Veja um exemplo de link direto que contém um URI, uma ação e um tipo MIME:

<fragment android:id="@+id/a"
          android:name="com.example.myapplication.FragmentA"
          tools:layout="@layout/a">
        <deeplink app:url="www.example.com"
                app:action="android.intent.action.MY_ACTION"
                app:mimeType="type/subtype"/>
</fragment>

Você pode usar o Navigation Editor para criar um link direto implícito para um destino, desta forma:

  1. Na guia Design do Navigation Editor, selecione o destino do link direto.
  2. Clique em + na seção Deep Links do painel Attributes.
  3. Na caixa de diálogo Add Deep Link exibida, insira as informações do link direto.

    Observe o seguinte:

    • Os URIs sem um esquema são considerados HTTP ou HTTPS. Por exemplo, www.google.com corresponde a http://www.google.com e https://www.google.com.
    • Os marcadores de parâmetros de caminho na forma de {placeholder_name} correspondem a um ou mais caracteres. Por exemplo, http://www.example.com/users/{id} corresponde a http://www.example.com/users/4. O componente de navegação tenta analisar os valores dos marcadores nos tipos apropriados, combinando nomes dos marcadores com os argumentos definidos para o destino do link direto. Se nenhum argumento for definido com o mesmo nome, um tipo String padrão será usado como valor do argumento. Você pode usar o caractere curinga * para criar correspondência com 0 ou mais caracteres.
    • Os marcadores de parâmetros de consulta podem ser usados em vez de ou em conjunto com parâmetros de caminho. Por exemplo, http://www.example.com/users/{id}?myarg={myarg} corresponde a http://www.example.com/users/4?myarg=28.
    • Os marcadores de parâmetros de consulta para variáveis definidas com valores padrão ou anuláveis não precisam ser correspondentes. Por exemplo, http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2} corresponde a http://www.example.com/users/4?arg2=28 ou http://www.example.com/users/4?arg1=7. Esse não é o caso com parâmetros de caminho. Por exemplo, http://www.example.com/users?arg1=7&arg2=28 não corresponde ao padrão acima porque o parâmetro de caminho necessário não é fornecido.
    • Os parâmetros de consulta irrelevantes não afetam a correspondência de URI de link direto. Por exemplo, http://www.example.com/users/{id} corresponde a http://www.example.com/users/4?extraneousParam=7, mesmo que extraneousParam não esteja definido no padrão de URI.
  4. Opcional: selecione Auto Verify para exigir que o Google verifique se você é o proprietário do URI. Para ver mais informações, consulte Verificar links de apps para Android.

  5. Clique em Adicionar. Um ícone de link será exibido acima do destino selecionado para indicar que o destino tem um link direto.

  6. Clique na guia Code para alternar para a visualização XML. Um elemento <deepLink> aninhado foi adicionado ao destino:

    <deepLink app:uri="https://www.google.com" />
    

Para ativar o link direto implícito, você também precisa fazer adições ao arquivo manifest.xml do app. Adicione um único elemento <nav-graph> a uma atividade que aponta para um gráfico de navegação existente, como mostrado no exemplo a seguir:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <application ... >

        <activity name=".MainActivity" ...>
            ...

            <nav-graph android:value="@navigation/nav_graph" />

            ...

        </activity>
    </application>
</manifest>

Ao criar seu projeto, o componente de navegação substitui o elemento <nav-graph> por elementos <intent-filter> gerados para corresponder a todos os links diretos no gráfico de navegação.

Ao acionar um link direto implícito, o estado da backstack depende do Intent implícito ter sido inicializado pela sinalização Intent.FLAG_ACTIVITY_NEW_TASK:

  • Se a sinalização estiver configurada, a pilha de retorno da tarefa será limpa e substituída pelo destino do link direto. Assim como no caso do link direto explícito, ao aninhar gráficos, o destino inicial de cada nível de aninhamento, ou seja, o destino inicial de cada elemento <navigation> na hierarquia, também é adicionado à pilha. Isso significa que quando um usuário pressiona o botão "Voltar" em um destino de link direto, ele navega pela pilha de navegação como se tivesse entrado no app a partir do ponto de entrada.
  • Se a sinalização não estiver configurada, você permanecerá na pilha de tarefas do app anterior, em que o link direto implícito foi acionado. Nesse caso, o botão "Voltar" levará você de volta ao app anterior, enquanto o botão "Para cima" iniciará a tarefa do app no destino pai hierárquico no gráfico de navegação.

Como processar links diretos

É altamente recomendável usar sempre o launchMode padrão de standard ao usar o componente de navegação. Ao usar o modo de inicialização standard, o componente de navegação processa automaticamente os links diretos chamando handleDeepLink() para processar qualquer link direto explícito ou implícito na Intent. No entanto, isso não acontecerá automaticamente se a Activity for reutilizada ao usar um launchMode alternativo, como singleTop. Nesse caso, é necessário chamar handleDeepLink() manualmente em onNewIntent(), conforme mostrado no exemplo a seguir:

Kotlin

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    navController.handleDeepLink(intent)
}

Java

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    navController.handleDeepLink(intent);
}

Outros recursos

Para saber mais sobre a navegação, consulte os recursos a seguir.

Exemplos

Codelabs

Vídeos