# Live-Updates für Android

Pushwoosh unterstützt Android Live-Updates über das `pushwoosh-liveupdates`-Modul (SDK 6.9.0 und höher). Ein Live-Update ist eine fortlaufende Benachrichtigung im Fortschrittsstil, die das System auf dem Sperrbildschirm, in der Benachrichtigungsleiste und als Status-Chip in der Statusleiste hervorhebt, damit Benutzer eine Aktivität verfolgen können, ohne Ihre App zu öffnen.

Der gesamte Lebenszyklus wird vom Server gesteuert: Ihr Backend sendet einen Push, wenn die Aktivität beginnt, weitere Pushes, während sie fortschreitet, und einen letzten Push, wenn sie endet. Das SDK rendert jeden einzelnen automatisch.

## Was sind Live-Updates?

Live-Updates wurden in Android 16 (API 36) eingeführt, um eine vom Benutzer initiierte, zeitkritische Aktivität von Anfang bis Ende anzuzeigen. Sie bauen auf den fortschrittsorientierten Benachrichtigungen der Plattform und der `Notification.ProgressStyle`-API auf. Konzeptionell sind sie das Android-Pendant zu den iOS Live-Aktivitäten.

Diese Seite behandelt nur die Pushwoosh-Integration. Informationen zum Plattformverhalten, zu den Regeln für die Hervorhebung und zu Designrichtlinien finden Sie in der offiziellen Android-Dokumentation:

- [Fortschrittsorientierte Benachrichtigungen](https://developer.android.com/about/versions/16/features/progress-centric-notifications)
- [Live-Update-Benachrichtigungen erstellen (Views)](https://developer.android.com/develop/ui/views/notifications/live-update)
- [Live-Update-Benachrichtigungen erstellen (Compose)](https://developer.android.com/develop/ui/compose/notifications/live-update)

## Wann sollten Live-Updates verwendet werden?

Live-Updates sind für eine Aktivität gedacht, die fortlaufend, vom Benutzer initiiert und zeitkritisch ist – etwas mit einem klaren Anfang und Ende, das dem Benutzer im Moment wichtig ist. Typische Szenarien für Pushwoosh-Kunden:

- **Essenslieferung** – Bestellung angenommen, wird vorbereitet, wird geliefert, kommt an.
- **Fahrdienste und Taxi** – Fahrer zugewiesen, auf dem Weg, kommt an, Fahrt läuft.
- **Bestell- und Sendungsverfolgung** – Live-Status einer Bestellung, die sich aktiv im Transit befindet.
- **Live-Sport und Medien** – Spielstand und Zeit, während das Spiel läuft.
- **Fitness** – ein aktives Training oder ein Lauf mit verstrichener Zeit und Fortschritt.
- **Fintech** – ein Transaktions- oder Verifizierungsprozess, der seine Phasen durchläuft.

Da der Lebenszyklus von realen Ereignissen gesteuert wird, die Ihr Backend bereits kennt (eine Bestellung ändert ihren Status, ein Kurier bewegt sich), ist ein Live-Update in der Regel ein einziger API-Aufruf, der in Ihren bestehenden Ereignisfluss integriert ist – nicht etwas, das eine Person manuell sendet.

<Aside type="caution">
Verwenden Sie Live-Updates nicht für Werbeaktionen, Chat-Nachrichten oder umgebungsbezogene Informationen und posten Sie niemals ein Live-Update erneut, das der Benutzer geschlossen hat. Android kann der App die Fähigkeit entziehen, hervorgehobene Benachrichtigungen zu posten. Befolgen Sie die [Android-Anleitung zur angemessenen Verwendung](https://developer.android.com/develop/ui/views/notifications/live-update#best-practices).
</Aside>

## Anforderungen

- Android 16 (API 36) oder neuer. Auf älteren Geräten bleibt das Modul inaktiv und jeder Live-Update-API-Aufruf ist eine sichere No-Op (Leeroperation).
- Pushwoosh Android SDK 6.9.0 oder höher.

## Das pushwoosh-liveupdates-Modul hinzufügen

Fügen Sie die Abhängigkeit zu Ihrer **app/build.gradle** hinzu:

```groovy
dependencies {
    implementation 'com.pushwoosh:pushwoosh-liveupdates:<latest-version>'
}
```

Ersetzen Sie `<latest-version>` durch die aktuelle Version von [Maven Central](https://mvnrepository.com/artifact/com.pushwoosh/pushwoosh-liveupdates).

Das Modul wird beim Start automatisch erkannt. Es deklariert die erforderliche `POST_PROMOTED_NOTIFICATIONS`-Berechtigung, registriert seinen eigenen Benachrichtigungskanal und fängt Live-Update-Pushes vor dem Standard-Benachrichtigungspfad ab. Es gibt keinen zusätzlichen Initialisierungscode – das SDK setzt die fortlaufenden und hervorgehobenen Flags, lädt das große Symbol herunter, ordnet Aktionsschaltflächen zu und postet die Benachrichtigung für Sie.

## Ein Live-Update senden

Sie senden Live-Updates über die [Messaging API v2](/de/developer/api-reference/messaging-api-v2/), indem Sie ein `live_update`-Objekt zum `android`-Inhaltsblock hinzufügen. Verwenden Sie eine `transactional`-Anfrage – ein Live-Update zielt auf den spezifischen Benutzer ab, dessen Aktivität es verfolgt. Das `schedule`-Feld ist erforderlich; `{ "after": "0s" }` sendet sofort. Der Lebenszyklus hat drei Operationen, die in `live_update.op` festgelegt werden:

- `OPERATION_START` – erster Push für eine Aktivität. Postet die fortlaufende Benachrichtigung.
- `OPERATION_UPDATE` – ein späterer Push für dieselbe Aktivität. Aktualisiert sie an Ort und Stelle, ohne Ton.
- `OPERATION_END` – abschließender Push. Schließt die Benachrichtigung.

Alle Pushes, die zur selben Aktivität gehören, müssen dieselbe `live_update.id` haben. Diese ID verbindet die Updates miteinander und wird auch verwendet, um das Update aus der App zu schließen.

Jeder Push beschreibt die Benachrichtigung vollständig – nichts wird vom vorherigen Push übernommen. Senden Sie jedes Feld, das Sie beibehalten möchten, wie die Segmente und das große Symbol, mit jedem `OPERATION_UPDATE` erneut; ein ausgelassenes Feld wird als nicht vorhanden gerendert.

### Live-Update-Parameter

Diese Schlüssel gehören in das `live_update`-Objekt des `android`-Inhaltsblocks. Titel, Text und großes Symbol verwenden die Standard-Android-Push-Felder (`title`, `body`, `custom_icon`), die zusammen mit `live_update` gesendet werden.

| Parameter | Typ | Beschreibung |
|---|---|---|
| `op` | string | Lebenszyklus-Operation: `OPERATION_START`, `OPERATION_UPDATE` oder `OPERATION_END`. Erforderlich. |
| `id` | string | Stabile Aktivitäts-ID, die von allen Pushes eines Live-Updates geteilt wird. Erforderlich. |
| `progress` | int | Fortschrittswert, gemessen an der Summe der Segmentlängen. |
| `progress_indeterminate` | bool | Zeigt eine unbestimmte Animation anstelle eines konkreten Wertes an. |
| `progress_bar` | bool | Zeigt die Fortschrittsleiste überhaupt an. Standard ist `true`. |
| `segments` | array | Geordnete Fortschrittssegmente, jedes `{ "color": "#RRGGBB", "length": N }`. |
| `extras` | object | Beliebige Daten, die an einen benutzerdefinierten Style-Provider übergeben werden. |
| `when` | int64 | Zeitanker im Header, in Epochen-Millisekunden. |
| `chronometer` | bool | Zeigt die Header-Zeit als laufenden Timer an. |
| `chronometer_count_down` | bool | Ein laufender Timer zählt herunter statt hoch. |
| `show_when` | bool | Zeigt die Header-Zeitspalte überhaupt an. Standard ist `true`. |

<Aside>
Der `op`-Wert muss einer der exakten Enum-Namen `OPERATION_START`, `OPERATION_UPDATE` oder `OPERATION_END` sein – Kurzformen werden ignoriert. Jedes Feld hat seinen nativen JSON-Typ: `segments` ist ein JSON-Array und `extras` ein JSON-Objekt, keine kodierten Zeichenketten.
</Aside>

Die vier Zeitfelder werden wie folgt kombiniert: Wenn `show_when` auf `false` gesetzt ist, wird die Zeit ausgeblendet; andernfalls ist `when` der Anker, `chronometer` verwandelt es in einen Live-Zähler und `chronometer_count_down` lässt diesen Zähler rückwärts laufen.

### Start-Push

```bash
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transactional": {
      "application": "XXXXX-XXXXX",
      "platforms": ["ANDROID"],
      "users": { "list": ["customer-42"] },
      "payload": {
        "content": {
          "localized_content": {
            "default": {
              "android": {
                "title": "Order #4521",
                "body": "We are preparing your order",
                "custom_icon": "https://example.com/restaurant.png",
                "live_update": {
                  "op": "OPERATION_START",
                  "id": "order_4521",
                  "progress": 1,
                  "segments": [
                    { "color": "#34A853", "length": 3 },
                    { "color": "#FBBC05", "length": 4 },
                    { "color": "#4285F4", "length": 3 }
                  ],
                  "extras": { "eta": "18:40" }
                }
              }
            }
          }
        }
      },
      "schedule": { "after": "0s" },
      "message_type": "MESSAGE_TYPE_TRANSACTIONAL"
    }
  }'
```

### Update-Push

Senden Sie ein `OPERATION_UPDATE` mit derselben `id`, wann immer die Aktivität fortschreitet. Wiederholen Sie die Segmente und das Symbol – ein Update, das sie auslässt, wird ohne sie gerendert.

```bash
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transactional": {
      "application": "XXXXX-XXXXX",
      "platforms": ["ANDROID"],
      "users": { "list": ["customer-42"] },
      "payload": {
        "content": {
          "localized_content": {
            "default": {
              "android": {
                "title": "Order #4521",
                "body": "Your courier is on the way",
                "custom_icon": "https://example.com/restaurant.png",
                "live_update": {
                  "op": "OPERATION_UPDATE",
                  "id": "order_4521",
                  "progress": 7,
                  "segments": [
                    { "color": "#34A853", "length": 3 },
                    { "color": "#FBBC05", "length": 4 },
                    { "color": "#4285F4", "length": 3 }
                  ]
                }
              }
            }
          }
        }
      },
      "schedule": { "after": "0s" },
      "message_type": "MESSAGE_TYPE_TRANSACTIONAL"
    }
  }'
```

### End-Push

Der abschließende Push benötigt nur die Operation und die ID.

```bash
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transactional": {
      "application": "XXXXX-XXXXX",
      "platforms": ["ANDROID"],
      "users": { "list": ["customer-42"] },
      "payload": {
        "content": {
          "localized_content": {
            "default": {
              "android": {
                "live_update": {
                  "op": "OPERATION_END",
                  "id": "order_4521"
                }
              }
            }
          }
        }
      },
      "schedule": { "after": "0s" },
      "message_type": "MESSAGE_TYPE_TRANSACTIONAL"
    }
  }'
```

## Das Erscheinungsbild anpassen

Das SDK liefert einen Standard-Fortschrittsstil, der aus `progress`, `progress_indeterminate` und `segments` aufgebaut ist. Um die volle Kontrolle über die Fortschrittsleiste zu übernehmen, implementieren Sie `LiveUpdateProgressStyleProvider` und gestalten Sie selbst ein `Notification.ProgressStyle`.

Der Provider ist der einzige Anpassungspunkt. Das SDK ist weiterhin für die Kanaleinrichtung, die fortlaufenden und hervorgehobenen Flags, das große Symbol, die Aktionsschaltflächen und die Header-Zeit zuständig – ein benutzerdefinierter Provider kann nur die Fortschrittsleiste gestalten, sodass er die Berechtigung zur Hervorhebung nicht beeinträchtigen kann. Er muss zustandslos sein: Leiten Sie den zurückgegebenen Stil nur vom bereitgestellten `LiveUpdateState` ab. Wenn er eine Ausnahme auslöst, greift das SDK auf den Standardstil zurück und die Benachrichtigung wird trotzdem gepostet.

<Tabs>
<TabItem label="Java">
```java
import android.app.Notification;
import androidx.annotation.NonNull;
import com.pushwoosh.liveupdates.LiveUpdateProgressStyleProvider;
import com.pushwoosh.liveupdates.LiveUpdateSegment;
import com.pushwoosh.liveupdates.LiveUpdateState;
import java.util.List;

public class OrderStyleProvider implements LiveUpdateProgressStyleProvider {
    @NonNull
    @Override
    public Notification.ProgressStyle createStyle(@NonNull LiveUpdateState state) {
        Notification.ProgressStyle style = new Notification.ProgressStyle();
        if (state.getProgress() != null) {
            style.setProgress(state.getProgress());
        }
        style.setProgressIndeterminate(state.isProgressIndeterminate());

        List<LiveUpdateSegment> segments = state.getSegments();
        int boundary = 0;
        for (int i = 0; i < segments.size(); i++) {
            LiveUpdateSegment seg = segments.get(i);
            style.addProgressSegment(
                new Notification.ProgressStyle.Segment(seg.getLength()).setColor(seg.getColor()));
            boundary += seg.getLength();
            if (i < segments.size() - 1) {
                style.addProgressPoint(new Notification.ProgressStyle.Point(boundary));
            }
        }
        return style;
    }
}
```
</TabItem>
<TabItem label="Kotlin">
```kotlin
import android.app.Notification
import com.pushwoosh.liveupdates.LiveUpdateProgressStyleProvider
import com.pushwoosh.liveupdates.LiveUpdateState

class OrderStyleProvider : LiveUpdateProgressStyleProvider {
    override fun createStyle(state: LiveUpdateState): Notification.ProgressStyle {
        val style = Notification.ProgressStyle()
        state.progress?.let { style.setProgress(it) }
        style.setProgressIndeterminate(state.isProgressIndeterminate)

        val segments = state.segments
        var boundary = 0
        segments.forEachIndexed { i, seg ->
            style.addProgressSegment(
                Notification.ProgressStyle.Segment(seg.length).setColor(seg.color))
            boundary += seg.length
            if (i < segments.size - 1) {
                style.addProgressPoint(Notification.ProgressStyle.Point(boundary))
            }
        }
        return style
    }
}
```
</TabItem>
</Tabs>

Registrieren Sie den Provider mit einem `<meta-data>`-Tag in der **AndroidManifest.xml**. Die Klasse muss einen öffentlichen, parameterlosen Konstruktor haben.

```xml
<meta-data
    android:name="com.pushwoosh.LIVE_UPDATE_STYLE_PROVIDER"
    android:value="com.example.OrderStyleProvider" />
```

Verwenden Sie `LiveUpdateState.getExtras()`, um das JSON zu lesen, das Sie in `live_update.extras` gesendet haben, und passen Sie den Stil an Ihre eigenen Geschäftsdaten an.

## Live-Updates aus Ihrer App verwalten

Der Server steuert jeden `OPERATION_START`, `OPERATION_UPDATE` und `OPERATION_END`, daher gibt es keine app-seitige API, um ein Live-Update zu posten oder zu aktualisieren. Die `PushwooshLiveUpdates`-Fassade deckt nur das ab, was der Server nicht tun kann – ein Update lokal zu schließen und zu prüfen, welche auf dem Bildschirm angezeigt werden.

```java
import com.pushwoosh.liveupdates.PushwooshLiveUpdates;

// Schließt ein bestimmtes Live-Update, wenn der Benutzer die Aktivität in der App beendet,
// ohne auf den abschließenden "end"-Push des Servers zu warten
PushwooshLiveUpdates.endLiveUpdate("order_4521");

// Listet die Aktivitäts-IDs auf, die derzeit von dieser App angezeigt werden
List<String> active = PushwooshLiveUpdates.getActiveIds();

// Löscht alles, was diese App anzeigt, zum Beispiel beim Abmelden
PushwooshLiveUpdates.endAllLiveUpdates();
```

Alle Methoden können sicher von jedem Thread aufgerufen werden und sind eine No-Op (Leeroperation) auf Geräten unter Android 16.

## Verwandte Links

- [Pushwoosh Android SDK Übersicht](/de/developer/pushwoosh-sdk/android-sdk/)
- [Pushwoosh Android SDK API-Referenz](https://pushwoosh.github.io/pushwoosh-android-sdk/)
- [Messaging-API](/de/developer/api-reference/messaging-api-v2/)
- [Android fortschrittsorientierte Benachrichtigungen](https://developer.android.com/about/versions/16/features/progress-centric-notifications)