Rozpoczynanie aktywności z powiadomienia

Gdy użytkownik rozpoczyna aktywność z poziomu powiadomienia, musisz zachować jego oczekiwane wrażenia związane z nawigacją. Naciśnięcie przycisku Wstecz musi spowodować powrót użytkownika do ekranu głównego w ramach normalnego przepływu pracy aplikacji, a otwarcie ekranu Ostatnie musi wyświetlić aktywność jako osobne zadanie. Aby zachować tę nawigację, rozpocznij aktywność w nowym zadaniu.

Podstawowe podejście do ustawiania działania po kliknięciu powiadomienia opisano w artykule Tworzenie podstawowego powiadomienia. Na tej stronie dowiesz się, jak skonfigurować PendingIntent dla działania powiadomienia, aby tworzyło ono nowe zadanie i stos wsteczny. Sposób wykonania tej czynności zależy od rodzaju rozpoczynanej aktywności:

  • Zwykła aktywność: to aktywność, która jest częścią normalnego procesu UX aplikacji. Gdy użytkownik przechodzi do działania z powiadomienia, nowe zadanie musi zawierać pełny stos wsteczny, dzięki czemu użytkownik może kliknąć przycisk Wstecz, aby przejść wyżej w hierarchii aplikacji.
  • Specjalna aktywność: użytkownik widzi tę aktywność tylko wtedy, gdy została ona uruchomiona z poziomu powiadomienia. W pewnym sensie to działanie rozszerza interfejs powiadomień, ponieważ dostarcza informacji, które trudno wyświetlić w samym powiadomieniu. Ta aktywność nie wymaga stosu wstecznego.

Konfigurowanie zwykłego działania PendingIntent

Aby rozpocząć zwykłą aktywność z poziomu powiadomienia, skonfiguruj PendingIntent za pomocą TaskStackBuilder, aby utworzyć nową listę wsteczną w ten sposób:

Określanie hierarchii aktywności aplikacji

Określ naturalną hierarchię aktywności, dodając atrybut android:parentActivityName do każdego elementu <activity> w pliku manifestu aplikacji. Przyjrzyj się temu przykładowi:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<!-- MainActivity is the parent for ResultActivity. -->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />
    ...
</activity>

Tworzenie obiektu PendingIntent ze stosem wstecznym

Aby rozpocząć działanie, które obejmuje stos wsteczny działań, utwórz instancję TaskStackBuilder i wywołaj addNextIntentWithParentStack(), przekazując do niej Intent dla działania, które chcesz rozpocząć.

Jeśli zdefiniujesz aktywność nadrzędną dla każdej aktywności zgodnie z opisem podanym wcześniej, możesz wywołać metodę getPendingIntent(), aby otrzymać PendingIntent, która zawiera cały stos wsteczny.

// Create an Intent for the activity you want to start.
val resultIntent = Intent(this, ResultActivity::class.java)
// Create the TaskStackBuilder.
val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {
    // Add the intent, which inflates the back stack.
    addNextIntentWithParentStack(resultIntent)
    // Get the PendingIntent containing the entire back stack.
    getPendingIntent(
        0,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
}

W razie potrzeby możesz dodać argumenty do Intent obiektów w stosie, wywołując funkcję TaskStackBuilder.editIntentAt(). Jest to czasami konieczne, aby zapewnić, że aktywność na stosie wstecznym wyświetla istotne dane, gdy użytkownik do niej przechodzi.

Następnie możesz przekazać PendingIntent do powiadomienia w zwykły sposób:

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentIntent(resultPendingIntent)
    // ...
}
with(NotificationManagerCompat.from(this)) {
    notify(NOTIFICATION_ID, builder.build())
}

Konfigurowanie elementu PendingIntent dla specjalnej aktywności

Ponieważ specjalna aktywność rozpoczynająca się od powiadomienia nie wymaga stosu wstecznego, możesz utworzyć PendingIntent, wywołując getActivity(). W pliku manifestu określ jednak odpowiednie opcje zadania.

  1. W pliku manifestu dodaj te atrybuty do elementu <activity>.

    android:taskAffinity=""
    W połączeniu z flagą FLAG_ACTIVITY_NEW_TASK, której używasz w kodzie, ustaw ten atrybut jako pusty, aby mieć pewność, że ta aktywność nie zostanie uwzględniona w domyślnym zadaniu aplikacji. Nie będzie to miało wpływu na istniejące zadania, które mają domyślne powiązanie z aplikacją.
    android:excludeFromRecents="true"
    Wyklucza nowe zadanie z ekranu Ostatnie, aby użytkownik nie mógł przypadkowo do niego wrócić.

    Pokazuje to poniższy przykład:

    <activity
    android:name=".ResultActivity"
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
    </activity>

  2. Utwórz i wyślij powiadomienie:

    1. Utwórz Intent, który rozpoczyna Activity.
    2. Ustaw Activity, aby rozpocząć nowe, puste zadanie, wywołując setFlags() z flagami FLAG_ACTIVITY_NEW_TASK i FLAG_ACTIVITY_CLEAR_TASK.
    3. Utwórz PendingIntent, dzwoniąc pod numer getActivity().

    Pokazuje to poniższy przykład:

    val notifyIntent = Intent(this, ResultActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    val notifyPendingIntent = PendingIntent.getActivity(
        this, 0, notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

  3. Przekaż PendingIntent do powiadomienia w zwykły sposób:

    val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
        setContentIntent(notifyPendingIntent)
        // ...
    }
    with(NotificationManagerCompat.from(this)) {
        notify(NOTIFICATION_ID, builder.build())
    }

Więcej informacji o różnych opcjach zadań i działaniu stosu wstecznego znajdziesz w artykule Zadania i stos wsteczny.