I dispositivi Wear OS vengono spesso utilizzati per esperienze di lunga durata, come il monitoraggio di un allenamento. Ciò presenta una sfida per l'esperienza utente: se un utente inizia un'attività e poi passa al quadrante, come fa a tornare indietro? Tornare all'app utilizzando l'avvio app può essere difficile, soprattutto quando si è in movimento, creando attrito non necessario.
La soluzione è abbinare una notifica in corso a un OngoingActivity
.
In questo modo, il dispositivo può visualizzare informazioni sull'attività di lunga durata
nell'interfaccia utente, attivando funzionalità come l'icona selezionabile nella
parte inferiore del quadrante. In questo modo gli utenti sono consapevoli dell'attività in background e
possono tornare all'app con un solo tocco.
Ad esempio, in questa app di allenamento, le informazioni possono essere visualizzate sul quadrante dello smartwatch dell'utente come icona di corsa selezionabile:
Figura 1. Indicatore di attività.
Una notifica continua mostra anche informazioni nella sezione Recenti del launcher delle app globale. In questo modo, gli utenti hanno un altro posto comodo per vedere lo stato dell'attività e interagire di nuovo con l'app:
Figura 2. Avvio app globale.
Di seguito sono riportate alcune situazioni in cui è consigliabile utilizzare una notifica continua legata a un'attività in corso:
Figura 3. Timer:esegue attivamente il conto alla rovescia e termina quando il timer viene messo in pausa o arrestato.
Figura 4. Indicazioni stradali passo passo: annuncia le indicazioni per una destinazione. Termina quando l'utente raggiunge la destinazione o interrompe la navigazione.
Figura 5. Contenuti multimediali:riproduce musica durante una sessione. Termina immediatamente dopo che l'utente mette in pausa la sessione.
Wear crea automaticamente attività in corso per le app multimediali.
Per un esempio dettagliato di creazione di attività in corso per altri tipi di app, consulta il codelab Attività in corso.
Configura
Per iniziare a utilizzare l'API Ongoing Activity nella tua app, aggiungi le seguenti
dipendenze al file build.gradle
della tua app:
dependencies {
implementation "androidx.wear:wear-ongoing:1.1.0"
implementation "androidx.core:core:1.17.0"
}
Creare un'attività continua
La procedura prevede tre passaggi:
- Crea un
NotificationCompat.Builder
standard e configuralo come in corso. - Crea e configura un oggetto
OngoingActivity
, passandogli il generatore di notifiche. - Applica l'attività in corso al generatore di notifiche e pubblica la notifica risultante.
Crea e configura la notifica
Inizia creando un NotificationCompat.Builder
. Il passaggio chiave è chiamare
setOngoing(true)
per contrassegnarla come notifica costante. In questa fase puoi anche impostare altre proprietà di notifica, come l'icona piccola e la categoria.
// 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!
Crea OngoingActivity
Successivamente, crea un'istanza di OngoingActivity
utilizzando il relativo builder. OngoingActivity.Builder
richiede un Context
, un ID notifica e l'NotificationCompat.Builder
che hai creato nel passaggio precedente.
Configura le proprietà chiave che verranno visualizzate nelle nuove superfici dell'interfaccia utente:
- Icone animate e statiche: fornisci icone visualizzate sul quadrante dell'orologio in modalità attiva e Ambient.
- Intent di tocco: un
PendingIntent
che riporta l'utente alla tua app quando tocca l'icona dell'attività in corso. Puoi riutilizzarependingIndent
creato nel passaggio precedente.
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()
Applica alla notifica e al post
Il passaggio finale consiste nel collegare il OngoingActivity
alla notifica e poi
pubblicarla. Il metodo ongoingActivity.apply()
modifica il builder di notifiche originale, aggiungendo i dati necessari in modo che il sistema possa visualizzarli sulle superfici aggiuntive. Dopo averlo applicato, puoi creare e pubblicare la notifica
come di consueto.
// This call modifies notificationBuilder to include the ongoing activity data. ongoingActivity.apply(applicationContext) // Post the notification. startForeground(NOTIFICATION_ID, notificationBuilder.build())
Aggiungere testo di stato dinamico ad Avvio app
Il codice precedente aggiunge l'icona toccabile al quadrante. Per fornire aggiornamenti in tempo reale ancora più ricchi nella sezione Recenti dell'app di avvio, crea un oggetto Status
e allegalo al tuo OngoingActivity
. Se non
fornisci un Status
personalizzato, il sistema utilizza per impostazione predefinita il testo
dei contenuti della notifica (impostato utilizzando setContentText()
).
Per visualizzare il testo dinamico, utilizza un Status.Builder
. Puoi definire una stringa
modello con segnaposto e fornire Status.Part
oggetti per riempire questi
segnaposto. Il Status.Part
può essere dinamico, ad esempio un cronometro o un timer .
Il seguente esempio mostra come creare uno stato che visualizzi "Corri per [un cronometro]":
// 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()
Infine, collega questo Status
al tuo OngoingActivity
chiamando il numero setStatus()
sul OngoingActivity.Builder
.
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // ... // Add the status to the OngoingActivity. .setStatus(ongoingActivityStatus) .build()
Personalizzazioni aggiuntive
Oltre a Status
, puoi personalizzare le tue attività o notifiche in corso nei
seguenti modi. Tuttavia, queste personalizzazioni potrebbero non essere utilizzate, a seconda dell'implementazione dell'OEM.
Notifica continua
- Il set di categorie determina la priorità dell'attività in corso.
CATEGORY_CALL
: una chiamata vocale o video in arrivo o una richiesta di comunicazione sincrona simileCATEGORY_NAVIGATION
: una mappa o la navigazione passo passoCATEGORY_TRANSPORT
: controllo del trasporto dei contenuti multimediali per la riproduzioneCATEGORY_ALARM
: una sveglia o un timerCATEGORY_WORKOUT
: un allenamentoCATEGORY_LOCATION_SHARING
: categoria di condivisione temporanea della posizioneCATEGORY_STOPWATCH
: cronometro
Attività in corso
Icona animata: un vettore in bianco e nero, preferibilmente con uno sfondo trasparente. Viene visualizzato sul quadrante in modalità attiva. Se l'icona animata non viene fornita, viene utilizzata l'icona di notifica predefinita. L'icona di notifica predefinita è diversa per ogni applicazione.
Icona statica:un'icona vettoriale con sfondo trasparente. Viene visualizzato sul quadrante in modalità Ambient. Se l'icona animata non è impostata, viene utilizzata l'icona statica sul quadrante in modalità attiva. Se non viene fornito, viene utilizzata l'icona di notifica. Se non è impostato nessuno dei due, viene generata un'eccezione. (Avvio app utilizza ancora l'icona dell'app.)
OngoingActivityStatus:testo normale o
Chronometer
. Viene visualizzato nella sezione Recenti di Avvio app. Se non viene fornito, viene utilizzato il "testo contestuale" della notifica.Intent di tocco:un
PendingIntent
utilizzato per tornare all'app se l'utente tocca l'icona dell'attività in corso. Visualizzati sul quadrante o nell'elemento del launcher. Può essere diverso dall'intent originale utilizzato per avviare l'app. Se non viene fornito, viene utilizzato l'intent dei contenuti della notifica. Se non è impostato nessuno dei due, viene generata un'eccezione.LocusId
: ID che assegna la scorciatoia del launcher a cui corrisponde l'attività in corso. Viene visualizzato nell'avvio app nella sezione Recenti mentre l'attività è in corso. Se non viene fornito, il launcher nasconde tutti gli elementi delle app nella sezione Recenti dello stesso pacchetto e mostra solo l'attività in corso.ID attività in corso:ID utilizzato per distinguere le chiamate a
fromExistingOngoingActivity()
quando un'applicazione ha più di un'attività in corso.
Aggiornare un'attività continua
Nella maggior parte dei casi, gli sviluppatori creano una nuova notifica continua e una nuova attività continua quando devono aggiornare i dati sullo schermo. Tuttavia, l'API Ongoing
Activity offre anche metodi helper per aggiornare un OngoingActivity
se
vuoi conservare un'istanza anziché ricrearla.
Se l'app è in esecuzione in background, può inviare aggiornamenti all'API Ongoing Activity. Tuttavia, non farlo troppo spesso, perché il metodo di aggiornamento ignora le chiamate troppo vicine tra loro. Alcuni aggiornamenti al minuto sono ragionevoli.
Per aggiornare l'attività in corso e la notifica pubblicata, utilizza l'oggetto che
hai creato in precedenza e chiama update()
, come mostrato nell'esempio seguente:
ongoingActivity.update(context, newStatus)
Per comodità, esiste un metodo statico per creare un'attività continua.
OngoingActivity.recoverOngoingActivity(context)
.update(context, newStatus)
Interrompere un'attività in corso
Quando l'app ha terminato l'esecuzione come attività in corso, deve solo annullare la notifica in corso.
Puoi anche scegliere di annullare la notifica o l'attività in corso quando viene portata in primo piano, quindi ricrearla quando torna in background, ma non è obbligatorio.
Mettere in pausa un'attività in corso
Se la tua app ha un'azione di interruzione esplicita, continua l'attività in corso dopo che è stata riattivata. Per un'app senza un'azione di interruzione esplicita, termina l'attività quando viene sospesa.
Best practice
Quando utilizzi l'API Ongoing Activity, ricorda quanto segue:
Imposta un'icona statica per l'attività in corso, in modo esplicito o come fallback utilizzando la notifica. In caso contrario, riceverai un
IllegalArgumentException
.Utilizza icone vettoriali in bianco e nero con sfondi trasparenti.
Imposta un intent di tocco per l'attività in corso, esplicitamente o come fallback utilizzando la notifica. In caso contrario, riceverai un
IllegalArgumentException
.Se la tua app ha più di un'attività
MAIN LAUNCHER
dichiarata nel manifest, pubblica una scorciatoia dinamica e associala alla tua attività in corso utilizzandoLocusId
.
Pubblicare notifiche multimediali durante la riproduzione di contenuti multimediali sui dispositivi Wear OS
Se i contenuti multimediali vengono riprodotti su un dispositivo Wear OS, pubblica una notifica multimediale. In questo modo, il sistema può creare l'attività corrispondente.
Se utilizzi Media3, la notifica viene pubblicata automaticamente. Se crei la notifica manualmente, deve utilizzare MediaStyleNotificationHelper.MediaStyle
e l'MediaSession
corrispondente deve avere l'attività della sessione compilata.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Crea una notifica {:#notification}
- Coinvolgere gli utenti di Wear OS in nuovi modi con l'API Ongoing Activity
- Creare una notifica espandibile {:#expandable-notification}