Rozpoczynanie aktywności z powiadomienia

Rozpoczynając działanie z poziomu powiadomienia, musisz zachować oczekiwane wrażenia z nawigacji. Dotknięcie przycisku Wstecz musi spowodować powrót użytkownika do normalnego procesu pracy w aplikacji na ekran główny, a otwarcie ekranu Ostatnie musi wyświetlać aktywność jako osobne zadanie. Aby je zachować, rozpocznij działanie w nowym zadaniu.

Podstawowy sposób ustawiania działania powiadomień po kliknięciu opisaliśmy w sekcji Tworzenie podstawowego powiadomienia. Na tej stronie opisujemy, jak skonfigurować PendingIntent dla działania powiadomienia, aby utworzyć nowy stos zadań i stos wstecz. Sposób, w jaki to zrobisz, zależy od rodzaju aktywności:

Regularna aktywność
To działanie jest związane z zwykłym działaniem aplikacji. Gdy użytkownik przejdzie do działania z powiadomienia, nowe zadanie musi zawierać pełny stos wsteczny, który umożliwia mu kliknięcie przycisku Wstecz, aby przechodzić w górę hierarchii aplikacji.
Aktywność specjalna
Użytkownik widzi tę aktywność tylko wtedy, gdy jest ona uruchomiona z poziomu powiadomienia. Działanie to poszerza interfejs powiadomień, podając informacje trudne do wyświetlenia w samym powiadomieniu. Ta aktywność nie wymaga stosu wstecznego.

Konfigurowanie zwykłej aktywności PendingIntent

Aby rozpoczynać regularne działania z poziomu powiadomienia, skonfiguruj PendingIntent za pomocą TaskStackBuilder, aby tworzył nowy stos wsteczny w następujący sposób.

Definiowanie hierarchii aktywności w aplikacji

Określ naturalną hierarchię działań, 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 intencji PendingIntent za pomocą stosu wstecznego

Aby rozpocząć działanie obejmujące wsteczny stos działań, utwórz instancję TaskStackBuilder i wywołaj metodę addNextIntentWithParentStack(), która będzie przekazywać kod Intent odpowiadający działaniu, które chcesz rozpocząć.

Jeśli zdefiniujesz aktywność nadrzędną dla każdej aktywności w sposób opisany wcześniej, możesz wywołać metodę getPendingIntent(), aby otrzymać zdarzenie PendingIntent, które obejmuje cały stos wsteczny.

Kotlin

// 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)
}

Java

// Create an Intent for the activity you want to start.
Intent resultIntent = new Intent(this, ResultActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back
// stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack.
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

W razie potrzeby możesz dodać argumenty do obiektów Intent w stosie, wywołując TaskStackBuilder.editIntentAt(). Czasami jest to konieczne, aby mieć pewność, że aktywność w stosie wstecznym wyświetla istotne dane, gdy użytkownik przejdzie do niej.

Potem możesz jak zwykle przekazać PendingIntent do powiadomienia:

Kotlin

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

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentIntent(resultPendingIntent);
...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(NOTIFICATION_ID, builder.build());

Konfigurowanie specjalnej aktywności PendingIntent

Specjalna aktywność, która rozpoczyna się od powiadomienia, nie wymaga wstecznego stosu, dlatego możesz utworzyć PendingIntent, wywołując getActivity(). Określ jednak odpowiednie opcje zadań w pliku manifestu.

  1. W pliku manifestu dodaj do elementu <activity> poniższe atrybuty.
    android:taskAffinity=""
    W połączeniu z flagą FLAG_ACTIVITY_NEW_TASK używaną w kodzie ustaw ten atrybut jako pusty, aby mieć pewność, że ta aktywność nie zostanie przypisana do domyślnego zadania aplikacji. Nie będzie to miało wpływu na istniejące zadania z domyślną koligacją aplikacji.
    android:excludeFromRecents="true"
    Wyklucza nowe zadanie z ekranu Ostatnie, aby użytkownik nie mógł przypadkowo do niego wrócić.

    Widać to w tym przykładzie:

    <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 zaczyna się od Activity.
    2. Ustaw Activity tak, aby rozpoczynał się w nowym, pustym zadaniu, wywołując setFlags() z flagami FLAG_ACTIVITY_NEW_TASK i FLAG_ACTIVITY_CLEAR_TASK.
    3. Utwórz PendingIntent, wywołując getActivity().

    Widać to w tym przykładzie:

    Kotlin

    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
    )
    

    Java

    Intent notifyIntent = new Intent(this, ResultActivity.class);
    // Set the Activity to start in a new, empty task.
    notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    // Create the PendingIntent.
    PendingIntent notifyPendingIntent = PendingIntent.getActivity(
            this, 0, notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );
    
  3. Przekaż PendingIntent do powiadomienia w zwykły sposób:

    Kotlin

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

    Java

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
    builder.setContentIntent(notifyPendingIntent);
    ...
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(NOTIFICATION_ID, builder.build());
    

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