In Android ist ein Deeplink ein Link, der Sie direkt zu einem bestimmten Ziel in einer App führt.
Sie können in Ihrer App zwei verschiedene Arten von Deeplinks unterstützen: explizite und implizite. Wie Sie Deeplinks implementieren, hängt davon ab, welcher Diagramm
typ—XML or programmatic—in Ihrer App verwendet wird.
Expliziten Deeplink erstellen
Ein expliziter Deeplink ist eine einzelne Instanz
eines Deeplinks, der mit einem PendingIntent
Nutzer zu einem bestimmten Ort in Ihrer App führt. Sie können einen
expliziten Deeplink beispielsweise in einer Benachrichtigung oder einem App-Widget
verwenden.
Wenn ein Nutzer Ihre App über einen expliziten Deeplink öffnet, wird der Back-Stack der Aufgabe gelöscht und durch das Ziel des Deeplinks ersetzt. Beim
Verschachteln von Diagrammen,
wird dem Stack auch das Startziel aus jeder Verschachtelungsebene hinzugefügt, d. h. das Startziel
aus jedem <navigation> Element in der Hierarchie.
Wenn ein Nutzer also von einem Ziel eines Deeplinks aus auf die Schaltfläche „Zurück“ tippt, wird er im Navigations-Stack zurück nach oben geführt, so als hätte er Ihre App über den Einstiegspunkt aufgerufen.
Programmatische Diagramme
Wenn Ihr Navigationsdiagramm programmatisch definiert ist (wie es bei Navigation Compose oder der Kotlin DSL üblich ist), empfehlen wir, TaskStackBuilder zu verwenden, um das PendingIntent des Deeplinks zu erstellen.
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)
}
XML-Diagramme
Sie können die NavDeepLinkBuilder
Klasse verwenden, um ein PendingIntent,
zu erstellen, wie im folgenden Beispiel gezeigt. Wenn der angegebene Kontext keine
Activity ist, verwendet der Konstruktor
PackageManager.getLaunchIntentForPackage()
als Standard-Activity, die gestartet werden soll, sofern verfügbar.
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();
Standardmäßig startet NavDeepLinkBuilder Ihren expliziten Deeplink in der Standard-Start-Activity, die im Manifest Ihrer App deklariert ist. Wenn sich Ihr NavHost in einer anderen Activity befindet, müssen Sie den Komponentennamen angeben, wenn Sie den Deeplink-Builder erstellen:
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();
Wenn Sie einen ComponentName,
können Sie ihn direkt an den Builder übergeben:
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();
Wenn Sie einen vorhandenen NavController,
können Sie auch einen Deeplink mit
NavController.createDeepLink() erstellen.
Impliziten Deeplink erstellen
Ein impliziter Deeplink verweist auf ein bestimmtes Ziel in einer App. Wenn der Deeplink aufgerufen wird, z. B. wenn ein Nutzer auf einen Link klickt, kann Android Ihre App zum entsprechenden Ziel öffnen.
Deeplinks können nach URI, Intent-Aktionen und MIME-Typen abgeglichen werden. Sie können mehrere Abgleichstypen für einen einzelnen Deeplink angeben. Beachten Sie jedoch, dass der Abgleich von URI-Argumenten zuerst erfolgt, gefolgt von der Aktion und dann vom MIME-Typ.
Programmatische Diagramme
Wenn Sie Ihr Navigationsdiagramm programmatisch definieren (mit Navigation Compose oder der Kotlin DSL), definieren Sie Deeplinks im Code.
Compose
In Navigation Compose können Sie Deeplinks als Teil des composable()-Ziel-Builders mit dem Parameter deepLinks definieren. Er akzeptiert eine Liste von
NavDeepLink-Objekten, die Sie mit der Funktion
navDeepLink() erstellen können:
@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
Wenn Sie die Kotlin DSL verwenden, können Sie Deeplinks mit der
deepLink() Builder-Funktion im Ziel
block definieren:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
Intent-Filter für programmatische Diagramme hinzufügen
Da programmatische Navigationsdiagramme zur Laufzeit erstellt werden, kann die Navigations
komponente die entsprechenden <intent-filter> Elemente
in Ihrer AndroidManifest.xml nicht automatisch generieren. Stattdessen müssen Sie die entsprechenden
<intent-filter> Elemente manuell hinzufügen.
Fügen Sie Folgendes in das
entsprechende <activity> Element in Ihrem Manifest ein, um den Deeplink in den vorherigen Beispielen zu aktivieren:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
XML-Diagramme
Wenn Sie einen impliziten Deeplink in einem XML-basierten Diagramm erstellen möchten, können Sie das
<deepLink> Element direkt in der XML-Datei definieren oder den Navigationseditor verwenden.
Hier ist ein Beispiel für einen Deeplink, der einen URI, eine Aktion und einen MIME-Typ enthält:
<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>
Sie können auch den Navigationseditor verwenden, um einen impliziten Deeplink zu einem Ziel zu erstellen:
- Wählen Sie auf dem Tab Design des Navigationseditors das Ziel für den Deeplink aus.
- Klicken Sie im Bereich Deeplinks des Bereichs Attribute auf +.
Geben Sie im Dialogfeld Deeplink hinzufügen die Informationen für Ihren Deeplink ein.
Wichtige Hinweise:
- URIs ohne Schema werden entweder als
httpoderhttpsangenommen. Beispiel:www.google.comstimmt sowohl mithttp://www.google.comals auch mithttps://www.google.comüberein. - Platzhalter für Pfadparameter in der Form
{placeholder_name}stimmen mit einem oder mehreren Zeichen überein. Beispiel:http://www.example.com/users/{id}stimmt mithttp://www.example.com/users/4überein. Die Navigationskomponente versucht, die Platzhalterwerte in geeignete Typen zu parsen, indem sie Platzhalternamen mit den definierten Argumenten abgleicht, die für das Ziel des Deeplinks definiert sind. Wenn kein Argument mit demselben Namen definiert ist, wird für den Argumentwert ein Standard-String-Typ verwendet. Mit dem Platzhalter „.*“ können Sie 0 oder mehr Zeichen abgleichen. - Platzhalter für Abfrageparameter können anstelle von oder in Verbindung mit Pfadparametern verwendet werden. Beispiel:
http://www.example.com/users/{id}?myarg={myarg}stimmt mithttp://www.example.com/users/4?myarg=28überein. - Platzhalter für Abfrageparameter für Variablen, die mit Standard- oder Nullable-Werten definiert sind, müssen nicht übereinstimmen. Beispiel:
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}stimmt mithttp://www.example.com/users/4?arg2=28oderhttp://www.example.com/users/4?arg1=7überein. Bei Pfadparametern ist das nicht der Fall. Beispiel:http://www.example.com/users?arg1=7&arg2=28stimmt nicht mit dem obigen Muster überein, da der erforderliche Pfadparameter nicht angegeben ist. - Überflüssige Suchparameter wirken sich nicht auf den Abgleich von Deeplink-URIs aus. Beispiel:
http://www.example.com/users/{id}stimmt mithttp://www.example.com/users/4?extraneousParam=7überein, obwohlextraneousParamnicht im URI-Muster definiert ist.
- URIs ohne Schema werden entweder als
Optional: Klicken Sie das Kästchen Automatisch bestätigen an, damit Google bestätigen kann, dass Sie der Inhaber des URI sind. Weitere Informationen finden Sie unter Android-App-Links bestätigen.
Klicken Sie auf Hinzufügen. Über dem ausgewählten Ziel wird ein Linksymbol
angezeigt, um anzugeben, dass dieses Ziel einen
Deeplink hat.Klicken Sie auf den Tab Code , um zur XML-Ansicht zu wechseln. Dem Ziel wurde ein verschachteltes
<deepLink>Element hinzugefügt:<deepLink app:uri="https://www.google.com" />
Wenn Sie implizite Deeplinks für XML-basierte Diagramme aktivieren möchten, müssen Sie auch Änderungen an der Datei manifest.xml Ihrer App vornehmen. Fügen Sie einer Activity ein einzelnes <nav-graph>
Element hinzu, das auf ein vorhandenes Navigationsdiagramm verweist, wie im folgenden Beispiel gezeigt:
<?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>
Beim Erstellen Ihres Projekts ersetzt die Navigationskomponente das <nav-graph>
Element durch generierte <intent-filter> Elemente, um alle Deeplinks
im Navigationsdiagramm abzugleichen.
Implizite Deeplinks und der Back-Stack
Beim Auslösen eines impliziten Deeplinks hängt der Status des Back-Stacks ab von
ob der implizite Intent mit dem
Intent.FLAG_ACTIVITY_NEW_TASK
Flag gestartet wurde:
- Wenn das Flag festgelegt ist, wird der Back-Stack der Aufgabe gelöscht und durch das Ziel des Deeplinks ersetzt. Wie bei expliziten Deeplinks wird beim
Verschachteln von Diagrammen
dem Stack auch das Startziel aus jeder Verschachtelungsebene hinzugefügt, d. h. das Start
ziel aus jedem
<navigation>Element in der Hierarchie. Wenn ein Nutzer also von einem Ziel eines Deeplinks aus auf den Button „Zurück“ tippt, wird er im Navigations-Stack zurück nach oben geführt, so als hätte er Ihre App über den Einstiegspunkt aufgerufen. - Wenn das Flag nicht festgelegt ist, bleiben Sie im Back-Stack der vorherigen App, in der der implizite Deeplink ausgelöst wurde. In diesem Fall führt die Schaltfläche „Zurück“ Sie zurück zur vorherigen App, während die Schaltfläche „Nach oben“ die Aufgabe Ihrer App am hierarchischen übergeordneten Ziel in Ihrem Navigationsdiagramm startet.
Deeplinks verarbeiten
Wir empfehlen dringend, bei der Verwendung von Navigation immer den Standardwert
launchMode von standard
zu verwenden. Im Startmodus standard verarbeitet Navigation
Deeplinks automatisch, indem
handleDeepLink()
aufgerufen wird, um alle expliziten oder impliziten Deeplinks im Intent zu verarbeiten. Dies geschieht jedoch nicht automatisch, wenn die Activity bei Verwendung eines alternativen launchMode wie singleTop wiederverwendet wird. In diesem Fall ist es erforderlich, handleDeepLink() in onNewIntent() manuell aufzurufen, wie im folgenden Beispiel gezeigt:
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); }