Trabalhar com sessões

As sessões representam um intervalo de tempo em que os usuários para realizar uma atividade física. A API Sessions permite que o app crie sessões da academia.

Para atividades de condicionamento físico em andamento em que o usuário notifica seu app quando ele é iniciado. e terminar uma atividade de condicionamento físico, crie sessões em tempo real.

Você também pode inserir uma sessão na loja de fitness depois de uma atividade física. for concluída ou quando você importar dados e sessões de fora do Google Fit.

Criar sessões em tempo real

Para criar sessões para atividades de condicionamento físico contínuas, siga estas etapas:

  1. Inscrever-se para receber dados de condicionamento físico usando o RecordingClient.subscribe .

  2. Inicie uma sessão usando o SessionsClient.startSession quando o usuário iniciar a atividade de condicionamento físico.

  3. Pare a sessão usando o SessionsClient.stopSession quando o usuário encerra a atividade de condicionamento físico.

  4. Cancelar inscrição nos dados de condicionamento físico que você não está mais interessado em usar o RecordingClient.unsubscribe .

Iniciar uma sessão

Para iniciar uma sessão no app, use o 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));

Interromper uma sessão

Para interromper uma sessão no app, use o 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));

A sessão resultante tem os seguintes parâmetros:

  • Horário de início: a hora em que o app chamou a SessionsClient.startSession .

  • Horário de término: o horário em que o app chamou o SessionsClient.stopSession. .

  • Nome: o nome no objeto Session transmitido SessionsClient.startSession.

Inserir sessões na loja de condicionamento físico

Para inserir sessões com dados coletados anteriormente, faça o seguinte:

  1. Crie um objeto Session que especifique um intervalo de tempo e outros parâmetros informações imprecisas ou inadequadas.

  2. Crie um SessionInsertRequest com a sessão.

  3. Opcionalmente, adicione conjuntos de dados e agregue pontos de dados.

  4. Insira a sessão usando o método SessionsClient.insertSession .

Inserir uma sessão

Para inserir dados de condicionamento físico que contenham metadados de sessão nos dados de condicionamento físico do usuário histórico, crie primeiro uma instância 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();

A classe SessionInsertRequest fornece métodos convenientes para inserir dados. no histórico de condicionamento físico e criar uma sessão na mesma chamada para SessionsClient.insertSession. Os conjuntos de dados, se houver, são inseridos como se você chamava o HistoryClient.insertData e, em seguida, a sessão é criada.

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));

Inserir segmentos de atividade

Os dados de segmentos de atividade no Google Fit indicam qual atividade fitness que os usuários estão realizando em um determinado intervalo de tempo. Os dados do segmento de atividade são do tipo com.google.activity.segment (TYPE_ACTIVITY_SEGMENT) e é particularmente útil para dar pausas durante os treinos.

Por exemplo, se você criar uma sessão de corrida de 30 minutos com o Session.Builder.setActivity() mas o usuário fizer uma pausa de 10 minutos entre elas, o aplicativo mostram incorretamente que o usuário correu por 30 minutos. Desde que seu app possa detectar se o usuário estava caminhando ou correndo, os dados do segmento de atividade permitem que seu indicam que o usuário correu por 10 minutos, caminhou por 10 minutos e correu por mais 10 minutos. Outros apps também podem informar a atividade corretamente analisando os dados de segmento de atividade que você insere.

Para adicionar dados de segmento de atividade a uma sessão, crie um conjunto de dados que contenha pontos do tipo com.google.activity.segment. Cada um desses pontos representa intervalo de tempo contínuo em que o usuário realizou um único tipo de atividade.

O exemplo anterior de corrida e caminhada exigiria três segmentos de atividade pontos: um para correr durante os primeiros 10 minutos, outro para caminhada nos próximos 10 minutos e outra para execução nos ú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();

Ler dados de condicionamento físico usando sessões

A API Sessions permite acessar uma lista de sessões da loja de condicionamento físico que correspondem a alguns critérios. Por exemplo, você pode obter todas as sessões contidas em uma intervalo de tempo ou receber uma sessão específica por nome ou ID. Também é possível especificar se há interesse em sessões criadas pelo seu aplicativo ou por qualquer aplicativo.

Para obter uma lista de sessões que correspondem a alguns critérios, primeiro crie uma Instância de 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();

Em seguida, use o método SessionsClient.readSession :

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));

Ler dados de sono usando sessões

As sessões de sono são tratadas como diferentes de outras sessões de atividade. Por padrão, as respostas de leitura contêm apenas sessões de atividade, não sessões de sono.

Para incluir sessões de sono, use o includeSleepSessions ao criar o SessionReadRequest. Para incluir atividades e use includeSleepSessions e includeActivitySessions.

Mostrar sessões em outros apps

Para mostrar aos usuários uma visão mais detalhada de uma sessão específica em outro app, seu app pode invocar uma intent que contém as informações da sessão. Você pode especificar um app específico, como o app que criou a sessão. Ou, caso o app que criou a sessão não estiver instalado no dispositivo, você poderá permitir qualquer que pode mostrar atividades de condicionamento físico para responder à intent.

Para criar uma intent que mostre dados da sessão em outro app, use o método SessionsApi.ViewIntentBuilder classe:

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);

Receber intents de outros apps

Para registrar seu app e receber intents de outros apps de saúde e bem-estar, faça o seguinte: declarar um filtro de intent no manifesto semelhante ao seguinte:

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

Cada intent que seu app recebe do Google Fit corresponde a apenas uma atividade, mas é possível filtrar por vários tipos MIME em um único filtro de intents. O filtro de intent do seu app precisa incluir todas as atividades que o app suporta.

As intents de condicionamento físico incluem os seguintes extras:

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

Você pode obter dados desses extras da seguinte maneira:

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());
    }
}