In Android, un link diretto è un link che ti porta direttamente a una destinazione specifica all'interno di un'app.
Puoi supportare due tipi diversi di link diretti nella tua app: espliciti e impliciti. La modalità di implementazione dei link diretti varia a seconda del tipo di grafico
utilizzato dall'app:XML or programmatic.
Creare un deep link esplicito
Un deep link esplicito è una singola istanza
di un deep link che utilizza un PendingIntent
per indirizzare gli utenti a una posizione specifica all'interno dell'app. Ad esempio, potresti mostrare un
deep link esplicito come parte di una notifica o di un widget dell'app,
ad esempio.
Quando un utente apre l'app tramite un deep link esplicito, il back stack delle attività viene cancellato e sostituito con la destinazione del deep link. Quando
si annidano i grafici,
allo stack viene aggiunta anche la destinazione iniziale di ogni livello di annidamento, ovvero la destinazione iniziale
di ogni elemento <navigation> nella gerarchia.
Ciò significa che quando un utente preme il pulsante Indietro da una destinazione di link diretto, torna indietro nello stack di navigazione come se fosse entrato nell'app dal suo punto di ingresso.
Grafici programmatici
Se il grafico di navigazione è definito in modo programmatico (come di consueto in Navigation Compose o Kotlin DSL), ti consigliamo di utilizzare TaskStackBuilder per creare il PendingIntent del link diretto.
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)
}
Grafici XML
Puoi utilizzare la NavDeepLinkBuilder
classe per creare un PendingIntent,
come mostrato nell'esempio riportato di seguito. Tieni presente che se il contesto fornito non è un
Activity, il costruttore utilizza
PackageManager.getLaunchIntentForPackage()
come attività predefinita da avviare, se disponibile.
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();
Per impostazione predefinita, NavDeepLinkBuilder avvia il deep link esplicito nell'
attività di avvio predefinita Activity dichiarata nel manifest dell'app. Se NavHost si trova in un'altra attività, devi specificarne il nome del componente quando crei il builder del link diretto:
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 hai un ComponentName,
puoi passarlo direttamente al 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 hai un NavController,
puoi anche creare un link diretto utilizzando
NavController.createDeepLink().
Creare un deep link implicito
Un deep link implicito si riferisce a una destinazione specifica in un'app. Quando viene richiamato il deep link, ad esempio, quando un utente fa clic su un link, Android può aprire l'app nella destinazione corrispondente.
I link diretti possono essere abbinati in base a URI, azioni intent e tipi MIME. Puoi specificare più tipi di corrispondenza per un singolo link diretto, ma tieni presente che la corrispondenza degli argomenti URI ha la priorità, seguita dall'azione e poi dal tipo MIME.
Grafici programmatici
Se definisci il grafico di navigazione in modo programmatico (utilizzando Navigation Compose o Kotlin DSL), definisci i link diretti nel codice.
Compose
In Navigation Compose, puoi definire i link diretti come parte del builder di destinazione composable() utilizzando il parametro deepLinks. Accetta un elenco di
NavDeepLink oggetti, che puoi creare utilizzando la
navDeepLink() funzione:
@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)
}
Kotlin DSL
Quando utilizzi Kotlin DSL, puoi definire i link diretti utilizzando la
deepLink() funzione del builder all'interno del blocco di destinazione:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
Aggiungere filtri intent per i grafici programmatici
Poiché i grafici di navigazione programmatici vengono creati in fase di runtime, il componente Navigation
non può generare automaticamente gli elementi <intent-filter>corrispondenti
in AndroidManifest.xml. Devi invece aggiungere manualmente gli elementi appropriati
<intent-filter>.
Per attivare il link diretto negli esempi precedenti, aggiungi quanto segue all'interno dell'
elemento <activity> corrispondente nel manifest:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
Grafici XML
Per creare un deep link implicito in un grafico basato su XML, puoi definire l'
<deepLink> elemento direttamente in XML o utilizzare l'editor di navigazione.
Di seguito è riportato un esempio di link diretto che contiene un URI, un'azione e un 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>
Puoi anche utilizzare l'editor di navigazione per creare un deep link implicito a una destinazione come segue:
- Nella scheda Progettazione dell'editor di navigazione, seleziona la destinazione per il link diretto.
- Fai clic su + nella sezione Link diretti del riquadro Attributi.
Nella finestra di dialogo Aggiungi link diretto visualizzata, inserisci le informazioni per il link diretto.
Tieni presente quanto segue:
- Gli URI senza schema vengono considerati come
httpohttps. Ad esempio,www.google.comcorrisponde sia ahttp://www.google.comsia ahttps://www.google.com. - I segnaposto dei parametri del percorso nel formato
{placeholder_name}corrispondono a uno o più caratteri. Ad esempio,http://www.example.com/users/{id}corrisponde ahttp://www.example.com/users/4. Il componente Navigation tenta di analizzare i valori dei segnaposto in tipi appropriati abbinando i nomi dei segnaposto agli argomenti definiti per la destinazione del link diretto. Se non è definito alcun argomento con lo stesso nome, viene utilizzato un tipoStringpredefinito per il valore dell'argomento. Puoi utilizzare il carattere jolly .* per trovare la corrispondenza di 0 o più caratteri. - I segnaposto dei parametri di query possono essere utilizzati al posto dei parametri del percorso o in combinazione con questi. Ad esempio,
http://www.example.com/users/{id}?myarg={myarg}corrisponde ahttp://www.example.com/users/4?myarg=28. - Non è necessario che i segnaposto dei parametri di query per le variabili definite con valori predefiniti o nullable corrispondano. Ad esempio,
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}corrisponde ahttp://www.example.com/users/4?arg2=28ohttp://www.example.com/users/4?arg1=7. Questo non è il caso dei parametri del percorso. Ad esempio,http://www.example.com/users?arg1=7&arg2=28non corrisponde al pattern precedente perché non viene fornito il parametro del percorso obbligatorio. - I parametri di query estranei non influiscono sulla corrispondenza dell'URI del link diretto. Ad
esempio,
http://www.example.com/users/{id}corrispondehttp://www.example.com/users/4?extraneousParam=7, anche seextraneousParamnon è definito nel pattern URI.
- Gli URI senza schema vengono considerati come
(Facoltativo) Seleziona Verifica automatica per richiedere a Google di verificare che tu sia il proprietario dell'URI. Per maggiori informazioni, consulta Verificare gli app link Android.
Fai clic su Aggiungi. Sopra la destinazione selezionata viene visualizzata un'icona di link
per indicare che la destinazione ha un
link diretto.Fai clic sulla scheda Codice per passare alla visualizzazione XML. Alla destinazione è stato aggiunto un
<deepLink>elemento annidato:<deepLink app:uri="https://www.google.com" />
Per attivare i link diretti impliciti per i grafici basati su XML, devi anche apportare modifiche al file manifest.xml dell'app. Aggiungi un singolo <nav-graph>
elemento a un'attività che rimanda a un grafico di navigazione esistente, come mostrato
nell'esempio seguente:
<?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>
Quando crei il progetto, il componente Navigation sostituisce l'elemento <nav-graph>
con elementi <intent-filter> generati per corrispondere a tutti i link diretti
nel grafico di navigazione.
Link diretti impliciti e back stack
Quando si attiva un deep link implicito, lo stato del back stack dipende dal fatto che l'intent implicito sia stato avviato con il flag:IntentIntent.FLAG_ACTIVITY_NEW_TASK
- Se il flag è impostato, il back stack delle attività viene cancellato e sostituito con la destinazione del deep link. Come per i link diretti espliciti, quando
si annidano i grafici,
allo stack viene aggiunta anche la destinazione iniziale di ogni livello di annidamento, ovvero la destinazione
iniziale di ogni elemento
<navigation>nella gerarchia. Ciò significa che quando un utente preme il pulsante Indietro da una destinazione di link diretto, torna indietro nello stack di navigazione come se fosse entrato nell'app dal suo punto di ingresso. - Se il flag non è impostato, rimani nello stack delle attività dell'app precedente in cui è stato attivato il deep link implicito. In questo caso, il pulsante Indietro ti riporta all'app precedente, mentre il pulsante Su avvia l'attività dell'app nella destinazione principale gerarchica all'interno del grafico di navigazione.
Gestire i link diretti
Ti consigliamo vivamente di utilizzare sempre il predefinito
launchMode di standard
quando utilizzi Navigation. Quando utilizzi la modalità di avvio standard, Navigation
gestisce automaticamente i link diretti chiamando
handleDeepLink()
per elaborare eventuali link diretti espliciti o impliciti all'interno del Intent. Tuttavia, questo non avviene automaticamente se l'Activity viene riutilizzata quando si utilizza un launchMode alternativo come singleTop. In questo caso, è necessario chiamare manualmente handleDeepLink() in onNewIntent(), come mostrato nell'esempio seguente:
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); }