No Android, um link direto é aquele que leva você diretamente a um destino específico em um app.
É possível oferecer suporte a dois tipos diferentes de links diretos no app: explícito e implícito. A maneira como você implementa links diretos varia de acordo com o tipo de gráfico
usado pelo app:XML or programmatic.
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.
Gráficos programáticos
Se o gráfico de navegação for definido de maneira programática (como é comum no Navigation Compose ou na DSL do Kotlin), recomendamos o uso de TaskStackBuilder para criar o link direto PendingIntent.
val id = "exampleId"
val context = LocalContext.current
val deepLinkIntent = Intent(
Intent.ACTION_VIEW,
"https://www.example.com/profile/$id".toUri(),
context,
MyActivity::class.java
)
val pendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(deepLinkIntent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
Gráficos XML
Você pode usar a NavDeepLinkBuilder
classe 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.
Gráficos programáticos
Se você definir o gráfico de navegação de maneira programática (usando o Navigation Compose ou a DSL do Kotlin), defina links diretos no código.
Escrever
No Navigation Compose, é possível definir links diretos como parte do builder de destino composable() usando o parâmetro deepLinks. Ele aceita uma lista de
NavDeepLink objetos, que podem ser criados usando a
navDeepLink() função:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
composable<Profile>(
deepLinks = listOf(
navDeepLink<Profile>(basePath = "$uri/profile")
)
) { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(id = profile.id)
}
DSL do Kotlin
Ao usar a DSL do Kotlin, é possível definir links diretos usando a
deepLink() função do builder no bloco de destino:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
Adicionar filtros de intent para gráficos programáticos
Como os gráficos de navegação programáticos são criados no ambiente de execução, o componente de navegação
não pode gerar automaticamente os elementos <intent-filter>correspondentes
em seu AndroidManifest.xml. Em vez disso, é necessário adicionar manualmente os elementos adequados
<intent-filter>.
Para ativar o link direto nos exemplos anteriores, adicione o código abaixo ao elemento
correspondente <activity> no manifesto:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
Gráficos XML
Para criar um link direto implícito em um gráfico baseado em XML, defina o
<deepLink> elemento diretamente no XML ou use o Navigation Editor.
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:
- Na guia Design do Navigation Editor, selecione o destino do link direto.
- Clique em + na seção Deep Links do painel Attributes.
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
httpouhttps. Por exemplo,www.google.comcorresponde ahttp://www.google.comehttps://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 ahttp://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 tipoStringpadrã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 ahttp://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 ahttp://www.example.com/users/4?arg2=28ouhttp://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=28nã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 ahttp://www.example.com/users/4?extraneousParam=7, mesmo queextraneousParamnão esteja definido no padrão de URI.
- Os URIs sem um esquema são considerados
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.
Clique em Adicionar. Um ícone de link
aparece acima do destino selecionado para indicar que o destino tem um
link direto.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 para gráficos baseados em XML, você também precisa fazer adições ao arquivo manifest.xml do app. Adicione um único <nav-graph>
elemento 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 <nav-graph>
elemento por elementos <intent-filter> gerados por para corresponder a todos os links diretos
no gráfico de navegação.
Links diretos implícitos e a backstack
Ao acionar um link direto implícito, o estado do backstack depende de
o Intent implícito ter sido inicializado com a
Intent.FLAG_ACTIVITY_NEW_TASK
sinalização:
- 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.
Processar links diretos
É altamente recomendável usar sempre o padrão
launchMode 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); }