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 uma PendingIntent para direcionar os usuários a um local específico do app. Você pode mostrar 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 usando um link direto explícito, a backstack 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 uma PendingIntent, como mostrado no exemplo abaixo. Se o contexto fornecido não for uma 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:uri="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 aparece 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 abaixo:

<?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 de a Intent implícita ter sido ou não inicializada pela sinalização Intent.FLAG_ACTIVITY_NEW_TASK:

  • Se a sinalização estiver configurada, a backstack da tarefa vai 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ê vai 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.

Codelabs

Vídeos