Health Services fornisce assistenza di prima classe per le app di allenamento tramite ExerciseClient
.
Con ExerciseClient
, la tua app può controllare quando un esercizio è in corso, aggiungere obiettivi di allenamento e ricevere aggiornamenti sullo stato dell'allenamento, sugli eventi di allenamento o su altre metriche desiderate. Per ulteriori informazioni, consulta l'elenco completo dei
tipi di esercizio supportati da Servizi sanitari.
Consulta l'esercizio di esempio su GitHub.
Aggiungi dipendenze
Per aggiungere una dipendenza da Health Services, devi aggiungere il repository Maven di Google al tuo progetto. Per ulteriori informazioni, consulta il repository Maven di Google.
Poi, nel file build.gradle
a livello di modulo, aggiungi la seguente dipendenza:
Groovy
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha05" }
Kotlin
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha05") }
Struttura dell'app
Utilizza la seguente struttura dell'app quando crei un'app per l'allenamento con Health Services:
- Mantieni le schermate e la navigazione all'interno di un'attività principale.
- Gestisci lo stato dell'allenamento, i dati dei sensori, l'attività in corso e i dati con un servizio in primo piano.
- Archivia i dati con Room e utilizza WorkManager per caricarli.
Quando ti prepari per un'attività fisica e durante l'allenamento, la tua attività potrebbe essere interrotta per diversi motivi. L'utente potrebbe passare a un'altra app o tornare al quadrante. Il sistema potrebbe mostrare qualcosa sopra la tua attività o lo schermo potrebbe spegnersi dopo un periodo di inattività.
Utilizza un ForegroundService
in esecuzione continua insieme a ExerciseClient
per contribuire a garantire il corretto funzionamento dell'intero allenamento.
L'utilizzo di un ForegroundService
ti consente di utilizzare l'API Attività in corso per mostrare un indicatore sulle superfici dello smartwatch, consentendo all'utente di tornare rapidamente all'allenamento.
È essenziale che tu richieda i dati sulla posizione in modo appropriato nel servizio in primo piano. Nel file manifest, specifica i tipi di servizio in primo piano e le autorizzazioni necessarie:
<manifest ...> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application ...> <!-- If your app is designed only for devices that run Wear OS 4 or lower, use android:foregroundServiceType="location" instead. --> <service android:name=".MyExerciseSessionRecorder" android:foregroundServiceType="health|location"> </service> </application> </manifest>
Utilizza
AmbientLifecycleObserver
per l'attività pre-allenamento, che contiene la chiamata prepareExercise()
e
per l'attività di allenamento. Tuttavia, non aggiornare il display durante l'allenamento
in modalità Ambient: questo perché Servizi per la salute raggruppa i dati dell'allenamento
quando lo schermo del dispositivo è in modalità Ambient per risparmiare energia, pertanto le informazioni
visualizzate potrebbero non essere recenti. Durante gli allenamenti, mostra dati significativi per l'utente, visualizzando informazioni aggiornate o una schermata vuota.
Controllare le funzionalità
Ogni ExerciseType
supporta determinati tipi di dati per le metriche e per gli obiettivi di allenamento. Controlla queste funzionalità all'avvio, perché possono variare in base al dispositivo. Un dispositivo potrebbe non supportare un determinato tipo di esercizio o una funzionalità specifica, come la pausa automatica. Inoltre, le funzionalità di un dispositivo
potrebbero cambiare nel tempo, ad esempio dopo un aggiornamento software.
All'avvio dell'app, esegui query sulle funzionalità del dispositivo e memorizza ed elabora quanto segue:
- Gli esercizi supportati dalla piattaforma.
- Le funzionalità supportate per ogni esercizio.
- I tipi di dati supportati per ogni esercizio.
- Le autorizzazioni richieste per ciascuno di questi tipi di dati.
Usa ExerciseCapabilities.getExerciseTypeCapabilities()
con
il tipo di esercizio che preferisci per scoprire quali tipi di metriche puoi richiedere, quali obiettivi di esercizio puoi configurare e quali altre funzionalità sono disponibili per quel tipo di esercizio. Ciò è mostrato nell'esempio seguente:
val healthClient = HealthServices.getClient(this /*context*/)
val exerciseClient = healthClient.exerciseClient
lifecycleScope.launch {
val capabilities = exerciseClient.getCapabilitiesAsync().await()
if (ExerciseType.RUNNING in capabilities.supportedExerciseTypes) {
runningCapabilities =
capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
}
}
All'interno di ExerciseTypeCapabilities
restituito,
supportedDataTypes
sono elencati i tipi di dati per i quali puoi richiedere dati. Questo varia in base al dispositivo, quindi attieniti alle indicazioni per non richiedere un DataType
non supportato, altrimenti la tua richiesta potrebbe non andare a buon fine.
Utilizza i campi
supportedGoals
e
supportedMilestones
per determinare se l'esercizio può supportare un obiettivo di allenamento che
vuoi creare.
Se la tua app consente all'utente di utilizzare la messa in pausa automatica, devi verificare che questa funzionalità sia supportata dal dispositivo utilizzando
supportsAutoPauseAndResume
.
ExerciseClient
rifiuta le richieste non supportate sul
dispositivo.
L'esempio seguente verifica il supporto del tipo di dati HEART_RATE_BPM
, della funzionalità dell'obiettivo STEPS_TOTAL
e della funzionalità di messa in pausa automatica:
// Whether we can request heart rate metrics.
supportsHeartRate = DataType.HEART_RATE_BPM in runningCapabilities.supportedDataTypes
// Whether we can make a one-time goal for aggregate steps.
val stepGoals = runningCapabilities.supportedGoals[DataType.STEPS_TOTAL]
supportsStepGoals =
(stepGoals != null && ComparisonType.GREATER_THAN_OR_EQUAL in stepGoals)
// Whether auto-pause is supported.
val supportsAutoPause = runningCapabilities.supportsAutoPauseAndResume
Registrati per ricevere aggiornamenti sullo stato dell'allenamento
Gli aggiornamenti degli esercizi vengono inviati a un ascoltatore. La tua app può registrare un solo ascoltatore alla volta. Configura l'ascoltatore prima di iniziare l'allenamento, come mostrato nell'esempio seguente. L'ascoltatore riceve solo aggiornamenti sugli esercizi di proprietà della tua app.
val callback = object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
val exerciseStateInfo = update.exerciseStateInfo
val activeDuration = update.activeDurationCheckpoint
val latestMetrics = update.latestMetrics
val latestGoals = update.latestAchievedGoals
}
override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
// For ExerciseTypes that support laps, this is called when a lap is marked.
}
override fun onAvailabilityChanged(
dataType: DataType<*, *>,
availability: Availability
) {
// Called when the availability of a particular DataType changes.
when {
availability is LocationAvailability -> // Relates to Location/GPS.
availability is DataTypeAvailability -> // Relates to another DataType.
}
}
}
exerciseClient.setUpdateCallback(callback)
Gestire la durata dell'allenamento
Servizi per la salute supporta al massimo un esercizio alla volta in tutte le app sul dispositivo. Se è in corso il monitoraggio di un esercizio e un'altra app avvia il monitoraggio di un nuovo esercizio, il primo esercizio viene interrotto.
Prima di iniziare l'esercizio, segui questi passaggi:
- Controlla se è già in corso il monitoraggio di un'attività e reagisci di conseguenza. Ad esempio, chiedi all'utente di confermare prima di sostituire un esercizio precedente e iniziare a monitorarne uno nuovo.
L'esempio seguente mostra come verificare la presenza di un esercizio esistente con
getCurrentExerciseInfoAsync
:
lifecycleScope.launch {
val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().await()
when (exerciseInfo.exerciseTrackedStatus) {
OTHER_APP_IN_PROGRESS -> // Warn user before continuing, will stop the existing workout.
OWNED_EXERCISE_IN_PROGRESS -> // This app has an existing workout.
NO_EXERCISE_IN_PROGRESS -> // Start a fresh workout.
}
}
Autorizzazioni
Quando utilizzi ExerciseClient
, assicurati che la tua app richieda e mantenga le
autorizzazioni necessarie.
Se la tua app utilizza dati LOCATION
, assicurati che richieda e mantenga anche le autorizzazioni appropriate.
Per tutti i tipi di dati, prima di chiamare prepareExercise()
o startExercise()
,
esegui le seguenti operazioni:
- Specifica le autorizzazioni appropriate per i tipi di dati richiesti nel file
AndroidManifest.xml
. - Verifica che l'utente abbia concesso le autorizzazioni necessarie. Per ulteriori informazioni, consulta Richiedere le autorizzazioni per le app. Servizi sanitari rifiuta la richiesta se le autorizzazioni necessarie non sono già state concesse.
Per i dati sulla posizione, svolgi i seguenti passaggi aggiuntivi:
- Verifica che il GPS sia attivo sul dispositivo utilizzando
isProviderEnabled(LocationManager.GPS_PROVIDER)
. Se necessario, chiedi all'utente di aprire le impostazioni di geolocalizzazione. - Assicurati che un
ForegroundService
con il valoreforegroundServiceType
appropriato venga mantenuto per tutto l'allenamento.
Prepararsi per un'attività fisica
Alcuni sensori, come il GPS o il battito cardiaco, potrebbero richiedere un breve tempo di riscaldamento oppure l'utente potrebbe voler vedere i suoi dati prima di iniziare l'allenamento. Il metodo facoltativo
prepareExerciseAsync()
consente a questi sensori di riscaldarsi e di ricevere i dati senza avviare
il timer per l'allenamento. activeDuration
non è interessato da questo
tempo di preparazione.
Prima di effettuare la chiamata al numero prepareExerciseAsync()
, controlla quanto segue:
Controlla l'impostazione di geolocalizzazione a livello di piattaforma. L'utente controlla questa impostazione nel menu Impostazioni principale. È diversa dal controllo delle autorizzazioni a livello di app.
Se l'impostazione è disattivata, comunica all'utente che ha negato l'accesso alla posizione e invitalo ad attivarla se la tua app richiede la posizione.
Verifica che la tua app disponga delle autorizzazioni di runtime per i sensori del corpo (livello API 35 o precedente) o per la frequenza cardiaca (livello API 36 e versioni successive), il riconoscimento attività e la posizione esatta. Per le autorizzazioni mancanti, chiedi all'utente le autorizzazioni di runtime, fornendo un contesto adeguato. Se l'utente non concede un'autorizzazione specifica,rimuovi i tipi di dati associati a quell'autorizzazione dalla chiamata a
prepareExerciseAsync()
. Se non vengono fornite autorizzazioni per i sensori corporei (battito cardiaco a livello API 36 e versioni successive) né per la posizione, non chiamareprepareExerciseAsync()
, poiché la chiamata di preparazione è specifica per l'acquisizione di una frequenza cardiaca stabile o di una correzione del segnale GPS prima di iniziare un'attività fisica. L'app può comunque ottenere distanza, passo, velocità e altre metriche basate sui passi che non richiedono queste autorizzazioni.
Per assicurarti che la chiamata a prepareExerciseAsync()
possa andare a buon fine:
- Utilizza
AmbientLifecycleObserver
per l'attività pre-allenamento che contiene la chiamata di preparazione. - Chiama
prepareExerciseAsync()
dal tuo servizio in primo piano. Se non è in servizio ed è legato al ciclo di vita dell'attività, la preparazione del sensore potrebbe essere interrotta inutilmente. - Chiama
endExercise()
per disattivare i sensori e ridurre il consumo di energia se l'utente esce dall'attività pre-allenamento.
L'esempio seguente mostra come chiamare prepareExerciseAsync()
:
val warmUpConfig = WarmUpConfig(
ExerciseType.RUNNING,
setOf(
DataType.HEART_RATE_BPM,
DataType.LOCATION
)
)
// Only necessary to call prepareExerciseAsync if body sensor (API level 35
// or lower), heart rate (API level 36+), or location permissions are given.
exerciseClient.prepareExerciseAsync(warmUpConfig).await()
// Data and availability updates are delivered to the registered listener.
Una volta che l'app è nello stato PREPARING
, gli aggiornamenti della disponibilità dei sensori vengono inviati in ExerciseUpdateCallback
tramite onAvailabilityChanged()
.
Queste informazioni possono quindi essere presentate all'utente, che può decidere se iniziare o meno l'allenamento.
Inizia l'allenamento
Quando vuoi avviare un esercizio, crea un ExerciseConfig
per configurare il tipo di esercizio, i tipi di dati per i quali vuoi ricevere le metriche e eventuali obiettivi o traguardi dell'esercizio.
Gli obiettivi di allenamento sono costituiti da un DataType
e da una condizione. Gli obiettivi di allenamento sono obiettivi una tantum che vengono attivati quando viene soddisfatta una condizione, ad esempio quando l'utente corre per una determinata distanza. È possibile impostare anche un traguardo per l'esercizio fisico. I traguardi dell'allenamento possono essere attivati più volte, ad esempio ogni volta che l'utente supera un determinato punto oltre la distanza impostata.
L'esempio seguente mostra come creare un obiettivo di ogni tipo:
const val CALORIES_THRESHOLD = 250.0
const val DISTANCE_THRESHOLD = 1_000.0 // meters
suspend fun startExercise() {
// Types for which we want to receive metrics.
val dataTypes = setOf(
DataType.HEART_RATE_BPM,
DataType.CALORIES_TOTAL,
DataType.DISTANCE
)
// Create a one-time goal.
val calorieGoal = ExerciseGoal.createOneTimeGoal(
DataTypeCondition(
dataType = DataType.CALORIES_TOTAL,
threshold = CALORIES_THRESHOLD,
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
)
)
// Create a milestone goal. To make a milestone for every kilometer, set the initial
// threshold to 1km and the period to 1km.
val distanceGoal = ExerciseGoal.createMilestone(
condition = DataTypeCondition(
dataType = DataType.DISTANCE_TOTAL,
threshold = DISTANCE_THRESHOLD,
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
),
period = DISTANCE_THRESHOLD
)
val config = ExerciseConfig(
exerciseType = ExerciseType.RUNNING,
dataTypes = dataTypes,
isAutoPauseAndResumeEnabled = false,
isGpsEnabled = true,
exerciseGoals = mutableListOf<ExerciseGoal<Double>>(calorieGoal, distanceGoal)
)
exerciseClient.startExerciseAsync(config).await()
}
Puoi anche contrassegnare i giri per tutti gli esercizi. Health Services fornisce un
ExerciseLapSummary
con le metriche aggregate nel periodo del ciclo.
L'esempio precedente mostra l'utilizzo di isGpsEnabled
, che deve essere true
quando si richiedono i dati sulla posizione. Tuttavia, l'utilizzo del GPS può essere utile anche per altre metriche.
Se ExerciseConfig
specifica la distanza come DataType
, per impostazione predefinita viene utilizzata la stima della distanza in base ai passi. Se attivi facoltativamente il GPS, le informazioni sulla posizione possono essere utilizzate per stimare la distanza.
Mettere in pausa, riprendere e terminare un allenamento
Puoi mettere in pausa, riprendere e terminare gli allenamenti utilizzando il metodo appropriato, ad esempio
pauseExerciseAsync()
o
endExerciseAsync()
.
Utilizza lo stato di ExerciseUpdate
come fonte attendibile. L'allenamento non viene considerato in pausa quando viene restituita la chiamata a pauseExerciseAsync()
, ma quando questo stato è riportato nel messaggio ExerciseUpdate
. Questo è un aspetto particolarmente importante da considerare quando si tratta di stati dell'interfaccia utente. Se l'utente preme il tasto di pausa, disabilita il tasto di pausa e chiama pauseExerciseAsync()
su Servizi sanitari. Attendi che i servizi sanitari raggiungano lo stato di pausa utilizzando ExerciseUpdate.exerciseStateInfo.state
, quindi imposta il pulsante su Riprendi. Questo perché l'aggiornamento dello stato dei servizi sanitari può richiedere più tempo rispetto alla pressione del pulsante, quindi se colleghi tutte le modifiche dell'interfaccia utente alle pressioni dei pulsanti, l'interfaccia utente può non essere sincronizzata con lo stato dei servizi sanitari.
Tieni presente quanto segue nelle seguenti situazioni:
- La pausa automatica è attivata:l'allenamento può essere messo in pausa o avviato senza bisogno di alcuna interazione da parte dell'utente.
- Un'altra app avvia un'attività fisica: l'allenamento potrebbe essere interrotto senza l'interazione dell'utente.
Se l'allenamento della tua app viene interrotto da un'altra app, la tua app deve gestire la chiusura in modo corretto:
- Salvare lo stato dell'allenamento parziale in modo che i progressi di un utente non vengano cancellati.
- Rimuovi l'icona Attività in corso e invia all'utente una notifica per informarlo che l'allenamento è stato interrotto da un'altra app.
Inoltre, gestisci il caso in cui le autorizzazioni vengono revocate durante un
esercizio in corso. Viene inviato utilizzando lo stato isEnded
, con un valore ExerciseEndReason
di AUTO_END_PERMISSION_LOST
. Gestisci questa richiesta in modo simile alla richiesta di chiusura: salva lo stato parziale, rimuovi l'icona Attività in corso e invia una notifica all'utente su cosa è successo.
L'esempio seguente mostra come verificare correttamente l'interruzione:
val callback = object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
if (update.exerciseStateInfo.state.isEnded) {
// Workout has either been ended by the user, or otherwise terminated
}
...
}
...
}
Gestire la durata attiva
Durante un esercizio, un'app può mostrare la durata attiva dell'allenamento. L'app, i servizi per la salute e l'unità di controllo micro (MCU) del dispositivo, ovvero il processore a basso consumo responsabile del monitoraggio dell'esercizio fisico, devono essere sincronizzati e avere la stessa durata attiva corrente. Per facilitare la gestione, Servizi sanitari invia un messaggio ActiveDurationCheckpoint
che fornisce un punto di ancoraggio da cui l'app può avviare il timer.
Poiché la durata attiva viene inviata dall'MCU e può richiedere un breve
periodo di tempo per arrivare nell'app, ActiveDurationCheckpoint
contiene due proprietà:
activeDuration
: il tempo di attività dell'eserciziotime
: quando è stata calcolata la durata attiva
Pertanto, nell'app la durata attiva di un esercizio può essere calcolata da ActiveDurationCheckpoint
utilizzando la seguente equazione:
(now() - checkpoint.time) + checkpoint.activeDuration
Questo tiene conto del piccolo delta tra la durata attiva calcolata sulla MCU e l'arrivo nell'app. Può essere utilizzato per generare un cronometro nell'app e contribuire a garantire che il timer dell'app sia perfettamente allineato con l'ora in Health Services e nell'MCU.
Se l'allenamento è in pausa, l'app attende di riavviare il timer nell'interfaccia utente
fino a quando il tempo calcolato non è trascorso rispetto a quello visualizzato attualmente dall'interfaccia utente.
Questo accade perché il segnale di pausa raggiunge i servizi sanitari e l'MCU con un minimo ritardo. Ad esempio, se l'app è in pausa a t=10 secondi, Health Services potrebbe non inviare l'aggiornamento PAUSED
all'app fino a t=10,2 secondi.
Lavorare con i dati di ExerciseClient
Le metriche per i tipi di dati per i quali la tua app è registrata vengono inviate nei messaggi
ExerciseUpdate
.
Il processore invia i messaggi solo quando è attivo o quando viene raggiunto un periodo di generazione di report massimo, ad esempio ogni 150 secondi. Non fare affidamento sulla frequenza ExerciseUpdate
per far avanzare un cronometro con activeDuration
. Consulta l'esempio di esercizio su GitHub per un esempio di come implementare un cronometro indipendente.
Quando un utente avvia un'attività fisica, i messaggi ExerciseUpdate
possono essere inviati frequentemente, ad esempio ogni secondo. Quando l'utente avvia l'allenamento, lo schermo potrebbe essere disattivato. I servizi sanitari possono quindi inviare i dati meno spesso, ma comunque campionati con la stessa frequenza, per evitare di riattivare il processore principale. Quando l'utente guarda lo schermo, tutti i dati in fase di aggregazione vengono immediatamente inviati alla tua app.
Controllare la frequenza di raggruppamento
In alcuni scenari, potresti voler controllare la frequenza con cui la tua app riceve determinati tipi di dati quando lo schermo è spento. Un oggetto BatchingMode
consente alla tua app di ignorare il comportamento di raggruppamento predefinito per ricevere i dati più di frequente.
Per configurare la frequenza di raggruppamento, completa i seguenti passaggi:
Controlla se la definizione
BatchingMode
specifica è supportata dal dispositivo:// Confirm BatchingMode support to control heart rate stream to phone. suspend fun supportsHrWorkoutCompanionMode(): Boolean { val capabilities = exerciseClient.getCapabilities() return BatchingMode.HEART_RATE_5_SECONDS in capabilities.supportedBatchingModeOverrides }
Specifica che l'oggetto
ExerciseConfig
deve utilizzare un determinatoBatchingMode
, come mostrato nel seguente snippet di codice.val config = ExerciseConfig( exerciseType = ExerciseType.WORKOUT, dataTypes = setOf( DataType.HEART_RATE_BPM, DataType.TOTAL_CALORIES ), // ... batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS) )
Facoltativamente, puoi configurare dinamicamente
BatchingMode
durante l'allenamento, invece di avere un comportamento di raggruppamento specifico che persiste per tutta la durata dell'allenamento:val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS) exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
Per cancellare il valore personalizzato di
BatchingMode
e tornare al comportamento predefinito, invia un insieme vuoto aexerciseClient.overrideBatchingModesForActiveExercise()
.
Timestamp
Il punto in tempo di ogni punto dati rappresenta la durata dall'avvio del dispositivo. Per convertirlo in un timestamp:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Questo valore può essere utilizzato con getStartInstant()
o getEndInstant()
per ogni punto dati.
Accuratezza dei dati
Ad alcuni tipi di dati possono essere associate informazioni sulla precisione a ogni punto dati.
Questo valore è rappresentato nella proprietà accuracy
.
Le classi HrAccuracy
e LocationAccuracy
possono essere compilate rispettivamente per i tipi di dati HEART_RATE_BPM
e LOCATION
. Se presente, utilizza la proprietà
accuracy
per determinare se ogni punto dati è sufficientemente accurato per la tua applicazione.
Archivia e carica i dati
Utilizza Room per mantenere i dati inviati da Health Services. Il caricamento dei dati avviene al termine dell'esercizio utilizzando un meccanismo come Work Manager. In questo modo, le chiamate di rete per il caricamento dei dati vengono rimandate al termine dell'esercizio, riducendo al minimo il consumo di energia durante l'esercizio e semplificando il lavoro.
Elenco di controllo dell'integrazione
Prima di pubblicare la tua app che utilizza ExerciseClient
di Servizi sanitari, consulta
la seguente lista di controllo per assicurarti che l'esperienza utente eviti alcuni problemi comuni.
Verifica che:
- L'app controlla le funzionalità del tipo di allenamento e le funzionalità del dispositivo ogni volta che viene eseguita. In questo modo, puoi rilevare quando un determinato dispositivo o esercizio non supporta uno tra i tipi di dati di cui ha bisogno la tua app.
- Richiedi e gestisci le autorizzazioni necessarie e specificale nel
tuo file manifest. Prima di chiamare
prepareExerciseAsync()
, la tua app conferma che le autorizzazioni di runtime sono state concesse. - La tua app utilizza
getCurrentExerciseInfoAsync()
per gestire i casi in cui:- È già in corso il monitoraggio di un esercizio e la tua app sostituisce l'esercizio precedente.
- Un'altra app ha interrotto l'allenamento. Quando l'utente riavvia l'app, viene visualizzato un messaggio che spiega che l'esercizio è stato interrotto perché un'altra app ha preso il controllo.
- Se utilizzi i dati di
LOCATION
:- La tua app gestisce un
ForegroundService
con il corrispondenteforegroundServiceType
per tutta la durata dell'esercizio (inclusa la chiamata di preparazione). - Verifica che il GPS sia attivo sul dispositivo utilizzando
isProviderEnabled(LocationManager.GPS_PROVIDER)
e chiedi all'utente di aprire le impostazioni di geolocalizzazione, se necessario. - Per casi d'uso esigenti, in cui la ricezione di dati sulla posizione con bassa latenza è di grande importanza, ti consigliamo di integrare il Fornitore di posizione combinato (FLP) e di utilizzare i relativi dati come correzione della posizione iniziale. Quando sono disponibili informazioni sulla posizione più stabili da parte dei servizi sanitari, utilizzale al posto di FLP.
- La tua app gestisce un
- Se la tua app richiede il caricamento di dati, eventuali chiamate di rete per il caricamento dei dati vengono posticipate fino al termine dell'esercizio. In caso contrario, durante l'esercizio, la tua app effettua le chiamate di rete necessarie con parsimonia.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Aggiornamenti dei dati passivi
- Servizi per la salute su Wear OS
- Guida introduttiva ai riquadri