Laufende Aktivitäten anzeigen

Wear OS-Geräte werden häufig für Aktivitäten verwendet, die über einen längeren Zeitraum laufen, z. B. zum Aufzeichnen eines Workouts. Diese Aktivitäten können auch wichtige Informationen liefern, die für den Nutzer relevant sind und auf die er schnell zugreifen muss.

Das stellt eine Herausforderung für die Nutzerfreundlichkeit dar: Wenn ein Nutzer eine Aufgabe startet und dann zum Zifferblatt wechselt, sollte er weiterhin Folgendes tun können:

  • Wichtige Updates erhalten
  • Mit einem Tippen zur Aufgabe zurückkehren

Die Rückkehr zur App über den Launcher kann schwierig sein, insbesondere unterwegs, und unnötige Reibung verursachen.

Ab Wear OS 7 besteht die Lösung darin, eine Benachrichtigung über laufende Aktivitäten mit einem OngoingActivity oder einer Live-Update-Benachrichtigung zu verknüpfen. So kann das Gerät Informationen zur Aktivität, die über einen längeren Zeitraum läuft, auf der gesamten Benutzeroberfläche anzeigen, z. B. das anklickbare Symbol unten auf dem Zifferblatt. Diese Anzeige informiert Nutzer über die Hintergrundaufgabe und bietet eine Möglichkeit, mit einem Tippen zur App zurückzukehren.

Eine laufende Aktivität oder ein Live-Update sorgt auch dafür, dass Ihre App länger sichtbar bleibt und das System nach einer bestimmten Zeit der Inaktivität nicht zum Zifferblatt zurückkehrt. Weitere Informationen finden Sie unter App auf Wear sichtbar halten.

Verwenden Sie eine laufende Aktivität oder eine Live Update-Benachrichtigung für Aktivitäten, die voraussichtlich länger als eine Minute dauern, oder in Fällen, in denen der Nutzer Ihre App wahrscheinlich verlässt, bevor die Aufgabe abgeschlossen ist.

Geeignete Anwendungsfälle:aufgezeichnete Workouts, Timer, aktive Mitfahrgelegenheiten, längere Sprachaufnahmen wie Besprechungen und Einkaufslisten, die verfügbar sein müssen, während sich der Nutzer in einem Geschäft befindet

Nicht geeignete Anwendungsfälle:Aufzeichnen kurzer Sprachnachrichten, Werbeaktionen, Status einer App, die aktualisiert wird, und bevorstehende Kalendertermine.

Wichtig: Die Verwendung einer OngoingActivity oder eines Live-Updates in diesen Szenarien ist gemäß den Wear OS App-Qualitätsrichtlinien WO-V4 erforderlich.

In dieser Workout-App können die Informationen beispielsweise auf dem Zifferblatt des Nutzers als anklickbares Laufsymbol angezeigt werden:

running-icon

Abbildung 1 : Aktivitätsanzeige

Eine Benachrichtigung über laufende Aktivitäten zeigt auch Informationen im Bereich Letzte des globalen App Launchers an. So können Nutzer den Status ihrer Aufgabe an einer weiteren praktischen Stelle sehen und wieder mit der App interagieren:

launcher

Abbildung 2 : Globaler Launcher

In den folgenden Situationen ist es sinnvoll, eine Benachrichtigung über laufende Aktivitäten zu verwenden, die mit einer laufenden Aktivität verknüpft ist:

Timer

Abbildung 3 : Timer:Zählt die Zeit aktiv herunter und endet, wenn der Timer pausiert oder beendet wird.

Karte

Abbildung 4 : Detaillierte Routenführung:Gibt Anweisungen zu einem Ziel aus. Endet, wenn der Nutzer das Ziel erreicht oder die Navigation beendet.

Musik

Abbildung 5 : Medien:Spielt während einer Sitzung Musik ab. Endet sofort, nachdem der Nutzer die Sitzung pausiert hat.

Wear erstellt automatisch laufende Aktivitäten für Media-Apps.

Im Codelab zu laufenden Aktivitäten finden Sie ein ausführliches Beispiel für das Erstellen laufender Aktivitäten für andere Arten von Apps.

Einrichtung

Wenn Sie die Ongoing Activity API in Ihrer App verwenden möchten, fügen Sie der Datei build.gradle Ihrer App die folgenden Abhängigkeiten hinzu:

dependencies {
  implementation "androidx.wear:wear-ongoing:1.1.0"
  implementation "androidx.core:core:1.19.0"
}

Laufende Aktivität erstellen

Der Prozess umfasst drei Schritte:

  1. Erstellen Sie einen Standard-NotificationCompat.Builder und konfigurieren Sie ihn als laufend.
  2. Erstellen und konfigurieren Sie ein OngoingActivity-Objekt und übergeben Sie den Benachrichtigungs-Builder an dieses Objekt.
  3. Wenden Sie die laufende Aktivität auf den Benachrichtigungs-Builder an und senden Sie die resultierende Benachrichtigung.

Benachrichtigung erstellen und konfigurieren

Erstellen Sie zuerst einen NotificationCompat.Builder. Der wichtigste Schritt ist, setOngoing(true) aufzurufen, um ihn als Benachrichtigung über laufende Aktivitäten zu kennzeichnen. Sie können in dieser Phase auch andere Benachrichtigungseigenschaften festlegen, z. B. das kleine Symbol und die Kategorie.

// Create a PendingIntent to pass to the notification builder
val pendingIntent =
    PendingIntent.getActivity(
        this,
        0,
        Intent(this, AlwaysOnActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        },
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
    )

val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("Always On Service")
    .setContentText("Service is running in background")
    .setSmallIcon(R.drawable.animated_walk)
    // Category helps the system prioritize the ongoing activity
    .setCategory(NotificationCompat.CATEGORY_WORKOUT)
    .setContentIntent(pendingIntent)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .setOngoing(true) // Important!

OngoingActivity erstellen

Erstellen Sie als Nächstes eine Instanz von OngoingActivity mit dem Builder. Für OngoingActivity.Builder sind ein Context, eine Benachrichtigungs-ID und der NotificationCompat.Builder erforderlich, den Sie im vorherigen Schritt erstellt haben.

Konfigurieren Sie die wichtigsten Eigenschaften, die auf den neuen UI-Oberflächen angezeigt werden:

  • Animierte und statische Symbole: Geben Sie Symbole an, die auf der Uhr im aktiven und im Inaktivmodus angezeigt werden.
  • Touch-Intent: Ein PendingIntent mit dem der Nutzer zu Ihrer App zurückkehren kann wenn er auf das Symbol für die laufende Aktivität tippt. Sie können das im vorherigen Schritt erstellte pendingIndent wiederverwenden.

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // Sets the icon that appears on the watch face in active mode.
        .setAnimatedIcon(R.drawable.animated_walk)
        // Sets the icon that appears on the watch face in ambient mode.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap target to bring the user back to the app.
        .setTouchIntent(pendingIntent)
        .build()

Auf die Benachrichtigung anwenden und senden

Im letzten Schritt wird die OngoingActivity mit der Benachrichtigung verknüpft und dann gesendet. Die Methode ongoingActivity.apply() ändert den ursprünglichen Benachrichtigungs-Builder und fügt die erforderlichen Daten hinzu, damit das System sie auf den zusätzlichen Oberflächen anzeigen kann. Nachdem Sie sie angewendet haben, können Sie die Benachrichtigung wie gewohnt erstellen und senden.

// This call modifies notificationBuilder to include the ongoing activity data.
ongoingActivity.apply(applicationContext)

// Post the notification.
startForeground(NOTIFICATION_ID, notificationBuilder.build())

Dynamischen Statustext zum Launcher hinzufügen

Mit dem vorherigen Code wird dem Zifferblatt das anklickbare Symbol hinzugefügt. Wenn Sie noch umfassendere Echtzeit-Updates im Bereich Letzte des Launchers bereitstellen möchten, erstellen Sie ein Status-Objekt und fügen Sie es Ihrer OngoingActivity hinzu. Wenn Sie keinen benutzerdefinierten Status angeben, verwendet das System standardmäßig den Inhaltstext der Benachrichtigung (der mit setContentText() festgelegt wird). Wenn Sie dynamischen Text anzeigen möchten, verwenden Sie einen Status.Builder. Sie können einen Vorlagenstring mit Platzhaltern definieren und Status.Part-Objekte angeben, um diese Platzhalter zu füllen. Der Status.Part kann dynamisch sein, z. B. eine Stoppuhr oder ein Timer.

Das folgende Beispiel zeigt, wie Sie einen Status erstellen, der „Run for [a stopwatch timer]“ (Lauf für [eine Stoppuhr]) anzeigt:

// Define a template with placeholders for the activity type and the timer.
val statusTemplate = "#type# for #time#"

// Set the start time for a stopwatch.
// Use SystemClock.elapsedRealtime() for time-based parts.
val runStartTime = SystemClock.elapsedRealtime()

val ongoingActivityStatus = Status.Builder()
    // Sets the template string.
    .addTemplate(statusTemplate)
    // Fills the #type# placeholder with a static text part.
    .addPart("type", Status.TextPart("Run"))
    // Fills the #time# placeholder with a stopwatch part.
    .addPart("time", Status.StopwatchPart(runStartTime))
    .build()

Verknüpfen Sie diesen Status schließlich mit Ihrer OngoingActivity, indem Sie setStatus() für den OngoingActivity.Builder aufrufen.

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // ...
        // Add the status to the OngoingActivity.
        .setStatus(ongoingActivityStatus)
        .build()

Zusätzliche Anpassungen

Neben Status können Sie Ihre laufende Aktivität oder Benachrichtigungen auf folgende Weise anpassen. Diese Anpassungen werden jedoch je nach Implementierung des OEM möglicherweise nicht verwendet.

Laufende Benachrichtigung

  • Die festgelegte Kategorie bestimmt die Priorität der laufenden Aktivität.
    • CATEGORY_CALL:ein eingehender Sprach- oder Videoanruf oder eine ähnliche synchrone Kommunikationsanfrage
    • CATEGORY_NAVIGATION:eine Karte oder eine detaillierte Routenführung
    • CATEGORY_TRANSPORT:Steuerung der Medienwiedergabe
    • CATEGORY_ALARM:ein Wecker oder Timer
    • CATEGORY_WORKOUT:ein Workout
    • CATEGORY_LOCATION_SHARING: Kategorie für die temporäre Standortfreigabe
    • CATEGORY_STOPWATCH:Stoppuhr

Laufende Aktivität

  • Animiertes Symbol:ein schwarzes und weißes Vektorsymbol, vorzugsweise mit transparentem Hintergrund. Wird auf dem Zifferblatt im Aktivmodus angezeigt. Wenn kein animiertes Symbol angegeben ist, wird das Standardsymbol für Benachrichtigungen verwendet. Das Standardsymbol für Benachrichtigungen ist für jede Anwendung anders.

  • Statisches Symbol:ein Vektorsymbol mit transparentem Hintergrund. Wird auf dem Zifferblatt im Inaktivmodus angezeigt. Wenn kein animiertes Symbol festgelegt ist, wird das statische Symbol auf dem Zifferblatt im Aktivmodus verwendet. Wenn auch kein statisches Symbol angegeben ist, wird das Benachrichtigungssymbol verwendet. Wenn keines von beiden festgelegt ist, wird eine Ausnahme ausgelöst. (Der App Launcher verwendet weiterhin das App-Symbol.)

  • OngoingActivityStatus:Nur-Text oder ein Chronometer. Wird im Bereich Letzte des App Launchers angezeigt. Wenn kein Status angegeben ist, wird der Benachrichtigungskontexttext verwendet.

  • Touch-Intent:Ein PendingIntent, mit dem zur App zurückgekehrt werden kann, wenn der Nutzer auf das Symbol für die laufende Aktivität tippt. Wird auf dem Zifferblatt oder im Launcher-Element angezeigt. Er kann sich vom ursprünglichen Intent unterscheiden, der zum Starten der App verwendet wurde. Wenn kein Touch-Intent angegeben ist, wird der Inhalts-Intent der Benachrichtigung verwendet. Wenn keines von beiden festgelegt ist, wird eine Ausnahme ausgelöst.

  • LocusId: ID, die die Launcher-Verknüpfung zuweist, der die laufende Aktivität entspricht. Wird im Launcher im Bereich Letzte angezeigt, während die Aktivität läuft. Wenn keine `LocusId` angegeben ist, werden im Launcher alle App-Elemente im Bereich Letzte aus demselben Paket ausgeblendet und nur die laufende Aktivität angezeigt.

  • ID der laufenden Aktivität: ID, die verwendet wird, um Aufrufe von fromExistingOngoingActivity() zu unterscheiden, wenn eine Anwendung mehrere laufende Aktivitäten hat.

Laufende Aktivität aktualisieren

Sie sollten die laufende Aktivität für die vorhandene Benachrichtigung aktualisieren, wenn Sie den Status ändern müssen, anstatt eine neue Benachrichtigung und eine neue laufende Aktivität zu erstellen. Verwenden Sie zum Aktualisieren der laufenden Aktivität und der gesendeten Benachrichtigung das zuvor erstellte Objekt und rufen Sie update() auf, wie im folgenden Beispiel gezeigt:

ongoingActivity.update(context, newStatus)

In Fällen, in denen es nicht möglich ist, einen Verweis auf die laufende Aktivität zu speichern, gibt es eine statische Methode, um die laufende Aktivität wiederherzustellen. Diese Methode ist jedoch weniger empfehlenswert:

OngoingActivity.recoverOngoingActivity(context)
    ?.update(context, newStatus)

Laufende Aktivität beenden

Wenn die App als laufende Aktivität ausgeführt wurde, muss nur die Benachrichtigung über laufende Aktivitäten abgebrochen werden.

Sie können die Benachrichtigung oder die laufende Aktivität auch abbrechen, wenn sie in den Vordergrund kommt, und sie dann wieder erstellen, wenn sie in den Hintergrund zurückkehrt. Dies ist jedoch nicht erforderlich.

Laufende Aktivität pausieren

Wenn Ihre App eine explizite Beendigungsaktion hat, setzen Sie die laufende Aktivität fort, nachdem sie pausiert wurde. Bei einer App ohne explizite Beendigungsaktion beenden Sie die Aktivität, wenn sie pausiert wird.

Wichtige Überlegungen

Beachten Sie bei der Verwendung der Ongoing Activity API Folgendes:

  • Legen Sie ein statisches Symbol für Ihre laufende Aktivität fest, entweder explizit oder als Fallback über die Benachrichtigung. Andernfalls wird eine IllegalArgumentException ausgelöst.

  • Verwenden Sie schwarze und weiße Vektorsymbole mit transparentem Hintergrund.

  • Legen Sie einen Touch-Intent für Ihre laufende Aktivität fest, entweder explizit oder als Fallback über die Benachrichtigung. Andernfalls wird eine IllegalArgumentException ausgelöst.

  • Wenn in Ihrer App im Manifest mehr als eine MAIN LAUNCHER-Aktivität deklariert ist, veröffentlichen Sie eine dynamische Verknüpfung und verknüpfen Sie sie mit Ihrer laufenden Aktivität über LocusId.

Medienbenachrichtigungen veröffentlichen, wenn Medien auf Wear OS-Geräten wiedergegeben werden

Wenn Medieninhalte auf einem Wear OS-Gerät wiedergegeben werden, veröffentlichen Sie eine Medien benachrichtigung. So kann das System die entsprechende laufende Aktivität erstellen.

Wenn Sie Media3 verwenden, wird die Benachrichtigung automatisch veröffentlicht. Wenn Sie Ihre Benachrichtigung manuell erstellen, sollte sie MediaStyleNotificationHelper.MediaStyle verwenden und die entsprechende MediaSession sollte die Sitzungsaktivität enthalten.