Deeplink für ein Ziel erstellen

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:

  1. Wählen Sie auf dem Tab Design des Navigationseditors das Ziel für den Deeplink aus.
  2. Klicken Sie im Bereich Deeplinks des Bereichs Attribute auf +.
  3. Geben Sie im Dialogfeld Deeplink hinzufügen die Informationen für Ihren Deeplink ein.

    Wichtige Hinweise:

    • URIs ohne Schema werden entweder als http oder https angenommen. Beispiel: www.google.com stimmt sowohl mit http://www.google.com als auch mit https://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 mit http://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 mit http://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 mit http://www.example.com/users/4?arg2=28 oder http://www.example.com/users/4?arg1=7 überein. Bei Pfadparametern ist das nicht der Fall. Beispiel: http://www.example.com/users?arg1=7&arg2=28 stimmt 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 mit http://www.example.com/users/4?extraneousParam=7 überein, obwohl extraneousParam nicht im URI-Muster definiert ist.
  4. 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.

  5. Klicken Sie auf Hinzufügen. Über dem ausgewählten Ziel wird ein Linksymbol angezeigt, um anzugeben, dass dieses Ziel einen Deeplink hat.

  6. 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);
}