Esta guía es compatible con la versión 1.1.0-alpha12 de Health Connect.
Las rutas de ejercicio permiten a los usuarios registrar una ruta de GPS de las actividades asociadas y compartir mapas de sus entrenamientos con otras apps.
En esta guía, se proporciona información para solicitar permisos al usuario y también se describe cómo las apps reciben permiso para escribir datos de ruta como parte de una sesión de ejercicio.
La función de lectura y escritura de las rutas de ejercicio incluye lo siguiente:
- Las apps crean un nuevo permiso de escritura para las rutas de ejercicio.
- La inserción se lleva a cabo escribiendo una sesión de ejercicio con una ruta como su campo.
- Lectura:
- El propietario de la sesión puede acceder a los datos con una lectura de la sesión
- Desde una app de terceros, a través de un diálogo que permite al usuario otorgar una lectura única de una ruta
Si el usuario no tiene permisos de escritura y no está configurada la ruta, esta no se actualiza.
Si tu app tiene un permiso de escritura de ruta y trata de actualizar una sesión pasando un objeto de sesión sin una ruta, se borra la ruta existente.
Permisos necesarios
El acceso a las rutas de ejercicio está protegido por los siguientes permisos:
android.permission.health.READ_EXERCISE_ROUTES
android.permission.health.WRITE_EXERCISE_ROUTE
Si deseas agregar la función de ruta de ejercicio a tu app, comienza por solicitar permisos de escritura para un tipo de datos específico.
También debes declarar un permiso de ejercicio, ya que cada ruta está asociada con una sesión de ejercicio (una sesión = un entrenamiento).
Este es el permiso que debes declarar para poder escribir rutas de ejercicio:
<application>
<uses-permission
android:name="android.permission.health.WRITE_EXERCISE_ROUTE" />
<uses-permission
android:name="android.permission.health.WRITE_EXERCISE" />
...
</application>
Para leer las rutas de ejercicio, debes solicitar los siguientes permisos:
<application>
<uses-permission
android:name="android.permission.health.READ_EXERCISE_ROUTES" />
<uses-permission
android:name="android.permission.health.READ_EXERCISE" />
...
</application>
Para solicitar permisos, usa el método PermissionController.createRequestPermissionResultContract()
cuando conectes tu app por primera vez a Health Connect. Estos son varios permisos que puedes solicitar:
- Leer datos de estado, incluidos los datos de ruta:
HealthPermission.getReadPermission(ExerciseSessionRecord::class)
- Escribir datos de estado, incluidos los datos de ruta:
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
- Escribir datos de ruta de ejercicio:
HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE
Cómo solicitar permisos al usuario
Después de crear una instancia de cliente, tu app debe solicitarle permisos al usuario. Los usuarios deben poder otorgar o rechazar permisos en cualquier momento.
Para hacerlo, crea un conjunto de permisos para los tipos de datos necesarios. Primero, asegúrate de que los permisos del conjunto se declaren en tu manifiesto de Android.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)
Usa getGrantedPermissions
para ver si tu app ya tiene otorgados los permisos necesarios. De lo contrario, usa createRequestPermissionResultContract
para solicitarlos. Se mostrará la pantalla de permisos de Health Connect.
// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
// Permissions successfully granted
} else {
// Lack of required permissions
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (granted.containsAll(PERMISSIONS)) {
// Permissions already granted; proceed with inserting or reading data
} else {
requestPermissions.launch(PERMISSIONS)
}
}
Como los usuarios pueden otorgar o revocar permisos en cualquier momento, tu app necesita verificar en forma periódica los permisos otorgados y controlar situaciones en las que se pierde el permiso.
Información que se incluye en un registro de sesión de ejercicio
Cada registro de sesión de ejercicio contiene la siguiente información:
- El tipo de ejercicio, por ejemplo, andar en bicicleta.
- La ruta del ejercicio, que contiene información como latitud, longitud y altitud
Agregaciones admitidas
No hay agregaciones admitidas para este tipo de datos.
Ejemplo de uso
Solicita una ruta o escribe una ruta desde una sesión.
Cómo solicitar una ruta desde una sesión
A continuación, se detalla cómo leer una sesión en Health Connect y solicitar una ruta desde esa sesión:
suspend fun readExerciseSessionAndRoute() {
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofHours(1))
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getReadPermission(ExerciseSessionRecord::class))) {
// The user doesn't allow the app to read exercise session data.
return
}
val readResponse =
healthConnectClient.readRecords(
ReadRecordsRequest(
ExerciseSessionRecord::class,
TimeRangeFilter.between(startTime, endTime)
)
)
val exerciseRecord = readResponse.records.first()
val recordId = exerciseRecord.metadata.id
// See https://developer.android.com/training/basics/intents/result#launch
// for appropriately handling ActivityResultContract.
val requestExerciseRouteLauncher = fragment.registerForActivityResul
(ExerciseRouteRequestContract()) { exerciseRoute: ExerciseRoute? ->
if (exerciseRoute != null) {
displayExerciseRoute(exerciseRoute)
} else {
// Consent was denied
}
}
val exerciseSessionRecord =
healthConnectClient.readRecord(ExerciseSessionRecord::class, recordId).record
when (val exerciseRouteResult = exerciseSessionRecord.exerciseRouteResult) {
is ExerciseRouteResult.Data ->
displayExerciseRoute(exerciseRouteResult.exerciseRoute)
is ExerciseRouteResult.ConsentRequired ->
requestExerciseRouteLauncher.launch(recordId)
is ExerciseRouteResult.NoData -> Unit // No exercise route to show
else -> Unit
}
}
fun displayExerciseRoute(route: ExerciseRoute?) {
val locations = route.route.orEmpty()
for (location in locations) {
// Handle location.
}
}
Cómo escribir una ruta desde una sesión
En el siguiente código, se muestra cómo registrar una sesión que incluye una ruta de ejercicio:
suspend fun InsertExerciseRoute(healthConnectClient: HealthConnectClient) {
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
getWritePermission(ExerciseSessionRecord::class))) {
// The user doesn't allow the app to write exercise session data.
return
}
val sessionStartTime = Instant.now()
val sessionDuration = Duration.ofMinutes(20)
val sessionEndTime = sessionStartTime.plus(sessionDuration)
val exerciseRoute =
if (grantedPermissions.contains(PERMISSION_WRITE_EXERCISE_ROUTE)) ExerciseRoute(
listOf(
ExerciseRoute.Location(
// Location times must be on or after the session start time
time = sessionStartTime,
latitude = 6.5483,
longitude = 0.5488,
horizontalAccuracy = Length.meters(2.0),
verticalAccuracy = Length.meters(2.0),
altitude = Length.meters(9.0),
), ExerciseRoute.Location(
// Location times must be before the session end time
time = sessionEndTime.minusSeconds(1),
latitude = 6.4578,
longitude = 0.6577,
horizontalAccuracy = Length.meters(2.0),
verticalAccuracy = Length.meters(2.0),
altitude = Length.meters(9.2),
)
)
)
else
// The user doesn't allow the app to write exercise route data.
null
val exerciseSessionRecord = ExerciseSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
title = "Morning Bike Ride",
exerciseRoute = exerciseRoute,
metadata = Metadata.manualEntry(
device = Device(type = Device.TYPE_PHONE)
),
)
val response = healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
}