W Androidzie precyzyjny link to link, który prowadzi bezpośrednio do określonego miejsca docelowego w aplikacji.
Aplikacja może obsługiwać 2 rodzaje precyzyjnych linków: explicit i implicit. Sposób implementacji precyzyjnych linków zależy od tego, jakiego typu wykresu – XML or programmatic – używa Twoja aplikacja.
Tworzenie precyzyjnego linku typu explicit
Jawny precyzyjny link to pojedynczy precyzyjny link, który za pomocą PendingIntent kieruje użytkowników do określonego miejsca w aplikacji. Jawny precyzyjny link możesz wyświetlać np. w powiadomieniu lub widżecie aplikacji.
Gdy użytkownik otworzy aplikację za pomocą precyzyjnego linku typu explicit, stos wsteczny zostanie wyczyszczony i zastąpiony miejscem docelowym precyzyjnego linku. Podczas zagnieżdżania wykresów do stosu dodawane jest też miejsce docelowe na początku każdego poziomu zagnieżdżenia, czyli miejsce docelowe na początku każdego elementu <navigation> w hierarchii.
Oznacza to, że gdy użytkownik naciśnie przycisk Wstecz na stronie docelowej precyzyjnego linku, wróci do poprzedniego elementu w stosie nawigacji, tak jakby wszedł do aplikacji z punktu wejścia.
Wykresy automatyzacji
Jeśli Twój wykres nawigacji jest zdefiniowany programowo (co jest typowe w przypadku Navigation Compose lub Kotlin DSL), zalecamy użycie TaskStackBuilder do utworzenia precyzyjnego linku 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)
}
Wykresy XML
Możesz użyć klasy NavDeepLinkBuilder, aby utworzyć PendingIntent, jak pokazano w przykładzie poniżej. Pamiętaj, że jeśli podany kontekst nie jestActivity, konstruktor używaPackageManager.getLaunchIntentForPackage() jako domyślnej aktywności do uruchomienia, jeśli jest dostępna.
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();
Domyślnie polecenie NavDeepLinkBuilder uruchamia precyzyjny link typu explicit w domyślnym uruchomieniu Activity zadeklarowanym w manifeście aplikacji. Jeśli NavHost znajduje się w innej aktywności, podczas tworzenia narzędzia do tworzenia precyzyjnych linków musisz podać nazwę komponentu:
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();
Jeśli masz ComponentName, możesz przekazać go bezpośrednio do konstruktora:
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();
Jeśli masz już NavController, możesz też utworzyć precyzyjny link za pomocą NavController.createDeepLink().
Tworzenie precyzyjnego linku typu implicit
Niejawny precyzyjny link odnosi się do konkretnego miejsca docelowego w aplikacji. Gdy precyzyjny link zostanie wywołany – na przykład gdy użytkownik kliknie link – Android może otworzyć aplikację w odpowiednim miejscu docelowym.
Precyzyjne linki można dopasowywać według identyfikatora URI, działań intencji i typów MIME. Możesz określić wiele typów dopasowania dla jednego linku do aplikacji, ale pamiętaj, że dopasowywanie argumentów URI ma wyższy priorytet niż dopasowywanie działania, a następnie typu MIME.
Wykresy automatyzacji
Jeśli definiujesz wykres nawigacji programowo (za pomocą Navigation Compose lub Kotlin DSL), precyzyjne linki określasz w kodzie.
Utwórz
W Navigation Compose możesz zdefiniować precyzyjne linki w ramach composable()
konstruktora miejsca docelowego za pomocą parametru deepLinks. Przyjmuje listę obiektów NavDeepLink, które możesz utworzyć za pomocą funkcji navDeepLink():
@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
W przypadku DSL w języku Kotlin możesz zdefiniować precyzyjne linki za pomocą funkcji konstruktora deepLink() w bloku miejsca docelowego:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
Dodawanie filtrów intencji do wykresów zautomatyzowanych
Zautomatyzowane wykresy nawigacji są tworzone w czasie działania aplikacji, więc komponent Navigation nie może automatycznie generować pasujących elementów <intent-filter> w pliku AndroidManifest.xml. Musisz ręcznie dodać odpowiednie elementy <intent-filter>.
Aby włączyć precyzyjny link w powyższych przykładach, dodaj w odpowiednim elemencie <activity> w pliku manifestu ten kod:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
Wykresy XML
Aby utworzyć w grafie opartym na XML-u niejawny precyzyjny link, możesz zdefiniować element
<deepLink> bezpośrednio w XML-u lub użyć edytora nawigacji.
Oto przykładowy precyzyjny link zawierający identyfikator URI, działanie i typ 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>
Możesz też utworzyć niejawny precyzyjny link do miejsca docelowego w Edytorze nawigacji w ten sposób:
- Na karcie Projekt w edytorze nawigacji wybierz miejsce docelowe precyzyjnego linku.
- W sekcji Linki bezpośrednie w panelu Atrybuty kliknij +.
W wyświetlonym oknie Dodaj precyzyjny link wpisz informacje o precyzyjnym linku.
Uwaga:
- Identyfikatory URI bez schematu są traktowane jako
httplubhttps. Na przykładwww.google.compasuje zarówno dohttp://www.google.com, jak i dohttps://www.google.com. - Symbole zastępcze parametrów ścieżki w formie
{placeholder_name}pasują do co najmniej 1 znaku. Na przykładhttp://www.example.com/users/{id}pasuje dohttp://www.example.com/users/4. Komponent nawigacji próbuje przeanalizować wartości zastępcze i przekształcić je w odpowiednie typy, dopasowując nazwy zmiennych do zdefiniowanych argumentów, które są zdefiniowane dla miejsca docelowego precyzyjnego linku. Jeśli nie zdefiniowano argumentu o tej samej nazwie, dla wartości argumentu używany jest domyślny typString. Za pomocą symbolu wieloznacznego .* możesz dopasować 0 lub więcej znaków. - Obiekty zastępcze parametrów zapytania mogą być używane zamiast parametrów ścieżki lub w połączeniu z nimi. Na przykład
http://www.example.com/users/{id}?myarg={myarg}pasuje dohttp://www.example.com/users/4?myarg=28. - Zmienne zastępcze parametrów zapytania dla zmiennych zdefiniowanych z wartościami domyślnymi lub dopuszczającymi wartość null nie muszą być zgodne. Na przykład wzorzec
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}pasuje dohttp://www.example.com/users/4?arg2=28lubhttp://www.example.com/users/4?arg1=7. W przypadku parametrów ścieżki tak nie jest. Na przykładhttp://www.example.com/users?arg1=7&arg2=28nie pasuje do powyższego wzorca, ponieważ nie podano wymaganego parametru ścieżki. - Dodatkowe parametry zapytania nie mają wpływu na dopasowywanie identyfikatorów URI precyzyjnych linków. Na przykład
http://www.example.com/users/{id}pasuje dohttp://www.example.com/users/4?extraneousParam=7, mimo żeextraneousParamnie jest zdefiniowany we wzorcu URI.
- Identyfikatory URI bez schematu są traktowane jako
(Opcjonalnie) Zaznacz Automatyczna weryfikacja, aby Google zweryfikowało, czy jesteś właścicielem identyfikatora URI. Więcej informacji znajdziesz w artykule Weryfikowanie linków do aplikacji na Androida.
Kliknij Dodaj. Nad wybranym miejscem docelowym pojawi się ikona linku
, co oznacza, że ma ono link bezpośredni.Kliknij kartę Kod, aby przełączyć się na widok XML. Do miejsca docelowego dodano zagnieżdżony element
<deepLink>:<deepLink app:uri="https://www.google.com" />
Aby włączyć niejawne precyzyjne linki w przypadku wykresów opartych na XML, musisz też wprowadzić zmiany w pliku manifest.xml aplikacji. Dodaj do aktywności pojedynczy element <nav-graph>, który wskazuje istniejący wykres nawigacji, jak pokazano w tym przykładzie:
<?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>
Podczas tworzenia projektu komponent Navigation zastępuje element <nav-graph> wygenerowanymi elementami <intent-filter>, aby dopasować wszystkie precyzyjne linki na wykresie nawigacji.
Precyzyjne linki typu implicit i stos wsteczny
Stan stosu wstecznego podczas wywoływania precyzyjnego linku typu implicit zależy od tego, czy Intent został uruchomiony z flagą Intent.FLAG_ACTIVITY_NEW_TASK:
- Jeśli flaga jest ustawiona, stos zadań jest czyszczony i zastępowany miejscem docelowym linku bezpośredniego. Podobnie jak w przypadku precyzyjnego linkowania, podczas zagnieżdżania wykresów do stosu dodawane jest też miejsce docelowe na początku każdego poziomu zagnieżdżenia, czyli miejsce docelowe na początku każdego elementu
<navigation>w hierarchii. Oznacza to, że gdy użytkownik naciśnie przycisk Wstecz w miejscu docelowym precyzyjnego linku, wróci do poprzedniego elementu w stosie nawigacji, tak jakby wszedł do aplikacji z punktu wejścia. - Jeśli flaga nie jest ustawiona, pozostaniesz na stosie zadań poprzedniej aplikacji, w której został wywołany precyzyjny link typu implicit. W takim przypadku przycisk Wstecz przenosi Cię z powrotem do poprzedniej aplikacji, a przycisk W górę rozpoczyna zadanie aplikacji w hierarchicznym miejscu docelowym nadrzędnym w grafie nawigacji.
Obsługa precyzyjnych linków
Podczas korzystania z nawigacji zdecydowanie zalecamy używanie domyślnego ustawienia launchMode, czyli standard. W standardtrybie uruchamiania biblioteka Navigation automatycznie obsługuje precyzyjne linki, wywołując handleDeepLink() w celu przetworzenia wszystkich jawnych lub niejawnych precyzyjnych linków w Intent. Nie dzieje się to jednak automatycznie, jeśli Activity jest ponownie używany podczas korzystania z alternatywnego launchMode, np. singleTop. W takim przypadku konieczne jest ręczne wywołanie handleDeepLink() w onNewIntent(), jak pokazano w tym przykładzie:
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); }