Trabaja con sesiones

Las sesiones representan un intervalo de tiempo durante el cual los usuarios realizar una actividad física. La API de Sessions permite que tu app cree sesiones en en la tienda de entrenamiento físico.

Para actividades físicas en curso en las que el usuario notifique a tu app cuando se inicie una actividad física, puedes crear sesiones en tiempo real.

También puedes insertar una sesión en la tienda luego de una actividad física cuando finalice o cuando importes sesiones y datos que no provengan de Google Fit.

Crea sesiones en tiempo real

Para crear sesiones para actividades físicas en curso, completa los siguientes pasos:

  1. Suscribirse a los datos de estado físico usando la función RecordingClient.subscribe .

  2. Inicia una sesión con la SessionsClient.startSession cuando el usuario inicia la actividad de entrenamiento.

  3. Detén la sesión con la tecla SessionsClient.stopSession cuando el usuario finaliza la actividad de entrenamiento.

  4. Cómo anular la suscripción a los datos de entrenamiento que ya no te interesa usar RecordingClient.unsubscribe .

Inicia una sesión

Para iniciar una sesión en tu app, usa el método SessionsClient.startSession:

Kotlin

// 1. Subscribe to fitness data
// 2. Create a session object
// (provide a name, identifier, description, activity and start time)
val session = Session.Builder()
    .setName(sessionName)
    .setIdentifier("UniqueIdentifierHere")
    .setDescription("Morning run")
    .setActivity(FitnessActivities.RUNNING)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .build()

// 3. Use the Sessions client to start a session:
Fitness.getSessionsClient(this, googleSigninAccount)
    .startSession(session)
    .addOnSuccessListener {
        Log.i(TAG, "Session started successfully!")
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was an error starting the session", e)
    }

Java

// 1. Subscribe to fitness data
// 2. Create a session object
// (provide a name, identifier, description, activity and start time)
Session session = new Session.Builder()
        .setName(sessionName)
        .setIdentifier("UniqueIdentifierHere")
        .setDescription("Morning run")
        .setActivity(FitnessActivities.RUNNING)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .build();

// 3. Use the Sessions client to start a session:
Fitness.getSessionsClient(this, googleSigninAccount)
        .startSession(session)
        .addOnSuccessListener(unused ->
                Log.i(TAG, "Session started successfully!"))
        .addOnFailureListener(e ->
                Log.w(TAG, "There was an error starting the session", e));

Cómo detener una sesión

Para detener una sesión en tu app, usa el método SessionsClient.stopSession:

Kotlin

// Invoke the SessionsClient with the session identifier
Fitness.getSessionsClient(this, googleSigninAccount)
    .stopSession(session.getIdentifier())
    .addOnSuccessListener {
        Log.i(TAG, "Session stopped successfully!")

        // Now unsubscribe from the fitness data (see
        // Recording Fitness data)
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was an error stopping the session", e)
    }

Java

// Invoke the SessionsClient with the session identifier
Fitness.getSessionsClient(this, googleSigninAccount)
        .stopSession(session.getIdentifier())
        .addOnSuccessListener (unused -> {
            Log.i(TAG, "Session stopped successfully!");
            // Now unsubscribe from the fitness data (see
            // Recording Fitness data)
        })
        .addOnFailureListener(e ->
                Log.w(TAG, "There was an error stopping the session", e));

La sesión resultante tiene los siguientes parámetros:

  • Hora de inicio: La hora a la que la app llamó a SessionsClient.startSession .

  • Hora de finalización: La hora a la que la app llamó a SessionsClient.stopSession .

  • Nombre: Es el nombre del objeto Session al que le pasas. SessionsClient.startSession

Insertar sesiones en la tienda de entrenamiento físico

Para insertar sesiones con datos que recopilaste anteriormente, haz lo siguiente:

  1. Crea un objeto Session que especifique un intervalo de tiempo y otro tipo de información.

  2. Crea un SessionInsertRequest con la sesión.

  3. También puedes agregar conjuntos de datos y datos agregados.

  4. Inserta la sesión con el botón SessionsClient.insertSession .

Cómo insertar una sesión

Para insertar datos de actividad física que contengan metadatos de sesiones en la actividad física del usuario historial, primero crea una instancia de SessionInsertRequest:

Kotlin

// Create a session with metadata about the activity.
val session = Session.Builder()
    .setName(SAMPLE_SESSION_NAME)
    .setIdentifier("UniqueIdentifierHere")
    .setDescription("Long run around Shoreline Park")

    .setActivity(FitnessActivities.RUNNING)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .setEndTime(endTime, TimeUnit.MILLISECONDS)
    .build()

// Build a session insert request
val insertRequest = SessionInsertRequest.Builder()
    .setSession(session)
    // Optionally add DataSets for this session.
    .addDataSet(dataset)
    .build()

Java

// Create a session with metadata about the activity.
Session session = new Session.Builder()
        .setName(SAMPLE_SESSION_NAME)
        .setIdentifier("UniqueIdentifierHere")
        .setDescription("Long run around Shoreline Park")

        .setActivity(FitnessActivities.RUNNING)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .setEndTime(endTime, TimeUnit.MILLISECONDS)
        .build();

// Build a session insert request
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
        .setSession(session)
        // Optionally add DataSets for this session.
        .addDataSet(dataset)
        .build();

La clase SessionInsertRequest proporciona métodos prácticos para insertar datos. al historial de entrenamiento y crear una sesión en la misma llamada a SessionsClient.insertSession Los conjuntos de datos, si los hay, se insertan como si había llamado HistoryClient.insertData y, luego, se crea la sesión.

Kotlin

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .insertSession(insertRequest)
    .addOnSuccessListener {
        Log.i(TAG, "Session insert was successful!")
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was a problem inserting the session: ", e)
    }

Java

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
        .insertSession(insertRequest)
        .addOnSuccessListener (unused ->
                Log.i(TAG, "Session insert was successful!"))
        .addOnFailureListener(e ->
        Log.w(TAG, "There was a problem inserting the session: ", e));

Insertar segmentos de actividad

Los datos del segmento de actividad en Google Fit indican qué actividad física de los usuarios durante un intervalo de tiempo determinado. Los datos del segmento de actividad son del tipo com.google.activity.segment (TYPE_ACTIVITY_SEGMENT) y es particularmente útil para descansar durante los entrenamientos.

Por ejemplo, si creas una sesión de correr de 30 minutos con la Session.Builder.setActivity() pero el usuario se toma un descanso de 10 minutos, tu app mostrar incorrectamente que el usuario corrió durante 30 minutos Siempre y cuando la app pueda detectar si el usuario estaba caminando o corriendo, los datos del segmento de actividad permiten que las indicaron que el usuario corrió durante 10 minutos, caminó durante 10 minutos y, luego, corrió durante 10 minutos más. Otras apps también pueden informar la actividad correctamente observa los datos del segmento de actividad que insertas.

Para agregar datos de segmentos de actividad a una sesión, crea un conjunto de datos que contenga puntos del tipo com.google.activity.segment. Cada uno de estos puntos representa un intervalo de tiempo continuo durante el cual el usuario realizó un solo tipo de actividad.

El ejemplo anterior de correr y caminar necesitaría tres segmentos de actividad puntos: uno para correr durante los primeros 10 minutos y otro para caminar durante los siguientes 10 minutos y otra para correr durante los últimos 10 minutos.

Kotlin

// Create a DataSet of ActivitySegments to indicate the runner walked for
// 10 minutes in the middle of a run.
val activitySegmentDataSource = DataSource.Builder()
    .setAppPackageName(this.packageName)
    .setDataType(DataType.TYPE_ACTIVITY_SEGMENT)
    .setStreamName(SAMPLE_SESSION_NAME + "-activity segments")
    .setType(DataSource.TYPE_RAW)
    .build()

val firstRunningDp = DataPoint.builder(activitySegmentDataSource)
    .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
    .setTimeInterval(startTime, startWalkTime, TimeUnit.MILLISECONDS)
    .build()

val walkingDp = DataPoint.builder(activitySegmentDataSource)
    .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.WALKING)
    .setTimeInterval(startWalkTime, endWalkTime, TimeUnit.MILLISECONDS)
    .build()

val secondRunningDp = DataPoint.builder(activitySegmentDataSource)
    .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
    .setTimeInterval(endWalkTime, endTime, TimeUnit.MILLISECONDS)
    .build()

val activitySegments = DataSet.builder(activitySegmentDataSource)
    .addAll(listOf(firstRunningDp, walkingDp, secondRunningDp))
    .build()

// Create a session with metadata about the activity.
val session = Session.Builder()
    .setName(SAMPLE_SESSION_NAME)
    .setDescription("Long run around Shoreline Park")
    .setIdentifier("UniqueIdentifierHere")
    .setActivity(FitnessActivities.RUNNING)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .setEndTime(endTime, TimeUnit.MILLISECONDS)
    .build()

// Build a session insert request
val insertRequest = SessionInsertRequest.Builder()
    .setSession(session)
    .addDataSet(activitySegments)
    .build()

Java

// Create a DataSet of ActivitySegments to indicate the runner walked for
// 10 minutes in the middle of a run.
DataSource activitySegmentDataSource = new DataSource.Builder()
        .setAppPackageName(getPackageName())
        .setDataType(DataType.TYPE_ACTIVITY_SEGMENT)
        .setStreamName(SAMPLE_SESSION_NAME + "-activity segments")
        .setType(DataSource.TYPE_RAW)
        .build();

DataPoint firstRunningDp = DataPoint.builder(activitySegmentDataSource)
        .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
        .setTimeInterval(startTime, startWalkTime, TimeUnit.MILLISECONDS)
        .build();

DataPoint walkingDp = DataPoint.builder(activitySegmentDataSource)
        .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.WALKING)
        .setTimeInterval(startWalkTime, endWalkTime, TimeUnit.MILLISECONDS)
        .build();

DataPoint secondRunningDp = DataPoint.builder(activitySegmentDataSource)
        .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
        .setTimeInterval(endWalkTime, endTime, TimeUnit.MILLISECONDS)
        .build();

DataSet activitySegments = DataSet.builder(activitySegmentDataSource)
        .addAll(Arrays.asList(firstRunningDp, walkingDp, secondRunningDp))
        .build();

// Create a session with metadata about the activity.
Session session = new Session.Builder()
        .setName(SAMPLE_SESSION_NAME)
        .setDescription("Long run around Shoreline Park")
        .setIdentifier("UniqueIdentifierHere")
        .setActivity(FitnessActivities.RUNNING)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .setEndTime(endTime, TimeUnit.MILLISECONDS)
        .build();

// Build a session insert request
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
        .setSession(session)
        .addDataSet(activitySegments)
        .build();

Cómo leer datos de entrenamiento mediante sesiones

La API de Sessions te permite obtener una lista de sesiones de la tienda de entrenamiento coinciden con algunos criterios. Por ejemplo, puedes obtener todas las sesiones contenidas en una un intervalo de tiempo u obtener una sesión en particular por nombre o ID. También puedes especificar si te interesan las sesiones que crea tu app o cualquier app.

Para obtener una lista de sesiones que coincidan con algunos criterios, primero crea un Instancia SessionReadRequest:

Kotlin

// Use a start time of 1 week ago and an end time of now.
val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusWeeks(1)

// Build a session read request
val readRequest = SessionReadRequest.Builder()
    .setTimeInterval(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
    .read(DataType.TYPE_SPEED)
    .setSessionName(SAMPLE_SESSION_NAME)
    .build()

Java

// Use a start time of 1 week ago and an end time of now.
ZonedDateTime endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
ZonedDateTime startTime = endTime.minusWeeks(1)

// Build a session read request
SessionReadRequest readRequest = new SessionReadRequest.Builder()
        .setTimeInterval(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
        .read(DataType.TYPE_SPEED)
        .setSessionName(SAMPLE_SESSION_NAME)
        .build();

Luego, usa SessionsClient.readSession método:

Kotlin

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .readSession(readRequest)
    .addOnSuccessListener { response ->
        // Get a list of the sessions that match the criteria to check the result.
        val sessions = response.sessions
        Log.i(TAG, "Number of returned sessions is: ${sessions.size}")
        for (session in sessions) {
            // Process the session
            dumpSession(session)

            // Process the data sets for this session
            val dataSets = response.getDataSet(session)
            for (dataSet in dataSets) {
                // ...
            }
        }
    }
    .addOnFailureListener { e ->
        Log.w(TAG,"Failed to read session", e)
    }

Java

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
        .readSession(readRequest)
        .addOnSuccessListener(response -> {
            // Get a list of the sessions that match the criteria to check the
            // result.
            List<Session> sessions = response.getSessions();
            Log.i(TAG, "Number of returned sessions is: ${sessions.size}");
            for (Session session : sessions) {
                // Process the session
                dumpSession(session);

                // Process the data sets for this session
                List<DataSet> dataSets = response.getDataSet(session);
                for (DataSet dataSet : dataSets) {
                    // ...
                }
            }
        })
        .addOnFailureListener(e ->
                Log.w(TAG,"Failed to read session", e));

Cómo leer los datos de sueño mediante sesiones

Las sesiones de sueño se tratan de manera diferente a otras sesiones de actividad. De forma predeterminada, Las respuestas de lectura contienen solo sesiones de actividad, no sesiones de sueño.

Para incluir sesiones de sueño, usa la includeSleepSessions cuando compiles tu SessionReadRequest. Para incluir tanto las actividades como sesiones, usa tanto includeSleepSessions como includeActivitySessions

Mostrar sesiones en otras apps

Para mostrarles a los usuarios una vista más detallada de una sesión específica en otra app, tu app puede invocar un intent que contenga la información de la sesión. Puedes especificar una app en particular, como la app que creó la sesión. O, en caso de que el app que creó la sesión no está instalada en el dispositivo, puedes permitir que que puede mostrar la actividad física para responder al intent.

Para crear un intent que muestre datos de sesión en una aplicación diferente, usa la SessionsApi.ViewIntentBuilder clase:

Kotlin

// Pass your activity object to the constructor
val intent = SessionsApi.ViewIntentBuilder(this)
    .setPreferredApplication("com.example.someapp") // optional
    .setSession(session)
    .build()

// Invoke the intent
startActivity(intent)

Java

// Pass your activity object to the constructor
Intent intent = new SessionsApi.ViewIntentBuilder(this)
        .setPreferredApplication("com.example.someapp") // optional
        .setSession(session)
        .build();

// Invoke the intent
startActivity(intent);

Cómo recibir intents de otras apps

Si quieres registrar tu app para que reciba intents de otras apps de salud y bienestar, sigue estos pasos: declara un filtro de intents en tu manifiesto que sea similar al siguiente:

<intent-filter>
    <action android:name="vnd.google.fitness.VIEW"/>
    <data android:mimeType="vnd.google.fitness.session/running"/>
</intent-filter>

Cada intent que la aplicación recibe de Google Fit solo tiene un pero puedes filtrar varios tipos de MIME en un solo filtro de intents. El filtro de intents de tu app debe incluir todas las actividades que esta admite.

Los intents de entrenamiento incluyen los siguientes extras:

  • vnd.google.gms.fitness.start_time
  • vnd.google.gms.fitness.end_time
  • vnd.google.gms.fitness.session

Puedes obtener datos de estos extras de la siguiente manera:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    val supportedType = Session.getMimeType(FitnessActivities.RUNNING)

    if (Intent.ACTION_VIEW == intent.action && supportedType == intent.type) {
        // Get the intent extras
        val startTime = Fitness.getStartTime(intent, TimeUnit.MILLISECONDS);
        val endTime = Fitness.getEndTime(intent, TimeUnit.MILLISECONDS)
        val session = Session.extract(intent)
    }
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    String supportedType = Session.getMimeType(FitnessActivities.RUNNING);

    if (Intent.ACTION_VIEW.equals(getIntent().getAction()) && supportedType.equals(getIntent().getType())) {
        // Get the intent extras
        long startTime = Fitness.getStartTime(getIntent(), TimeUnit.MILLISECONDS);
        long endTime = Fitness.getEndTime(getIntent(), TimeUnit.MILLISECONDS);
        Session session = Session.extract(getIntent());
    }
}