Lavorare con le sessioni

Le sessioni rappresentano un intervallo di tempo durante il quale gli utenti svolgono un'attività fisica. L'API Sessions consente alla tua app di creare sessioni nel negozio di fitness.

Per le attività di fitness in corso in cui l'utente notifica la tua app quando inizia e termina un'attività di fitness, puoi creare sessioni in tempo reale.

Puoi anche inserire una sessione nel negozio di fitness al termine di un'attività o quando importi dati e sessioni dall'esterno di Google Fit.

Crea sessioni in tempo reale

Per creare sessioni per le attività di fitness in corso, completa i seguenti passaggi:

  1. Iscriviti ai dati relativi all'attività fisica utilizzando il metodo RecordingClient.subscribe.

  2. Avvia una sessione utilizzando il metodo SessionsClient.startSession quando l'utente avvia l'attività fisica.

  3. Interrompi la sessione utilizzando il metodo SessionsClient.stopSession quando l'utente termina l'attività fisica.

  4. Annulla l'iscrizione ai dati sull'attività fisica che non ti interessano più utilizzando il metodo RecordingClient.unsubscribe.

Avvia una sessione

Per avviare una sessione nella tua app, utilizza il metodo 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));

Interrompere una sessione

Per interrompere una sessione nella tua app, utilizza il metodo 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 sessione risultante ha i seguenti parametri:

  • Ora di inizio: l'ora in cui la tua app ha chiamato il metodo SessionsClient.startSession.

  • Ora di fine: l'ora in cui la tua app ha chiamato il metodo SessionsClient.stopSession.

  • Nome: il nome nell'oggetto Session che trasmetti a SessionsClient.startSession.

Inserisci sessioni nel centro fitness

Per inserire sessioni con i dati raccolti in precedenza:

  1. Creare un oggetto Session che specifichi un intervallo di tempo e altre informazioni obbligatorie.

  2. Crea una SessionInsertRequest con la sessione.

  3. Facoltativamente, aggiungi set di dati e punti dati aggregati.

  4. Inserisci la sessione utilizzando il metodo SessionsClient.insertSession.

Inserisci una sessione

Per inserire i dati relativi all'attività fisica contenenti i metadati di sessione nella cronologia dell'attività fisica dell'utente, devi prima creare un'istanza 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();

Il corso SessionInsertRequest offre metodi pratici per inserire dati nella cronologia dell'attività fisica e creare una sessione nella stessa chiamata a SessionsClient.insertSession. Gli eventuali set di dati vengono inseriti come se avessi prima chiamato il metodo HistoryClient.insertData, quindi la sessione veniva creata.

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

Inserisci segmenti attività

I dati relativi ai segmenti di attività in Google Fit indicano quali attività di fitness gli utenti svolgono in un determinato intervallo di tempo. I dati del segmento attività sono di tipo com.google.activity.segment (TYPE_ACTIVITY_SEGMENT) e sono particolarmente utili per supportare le pause durante gli esercizi.

Ad esempio, se crei una sessione di corsa di 30 minuti con il metodo Session.Builder.setActivity(), ma l'utente fa una pausa di 10 minuti nel mezzo, la tua app mostrerà in modo errato che l'utente ha eseguito 30 minuti. Se l'app può rilevare se l'utente stava camminando o correndo, i dati relativi ai segmenti di attività consentono all'app di indicare che l'utente ha corso per 10 minuti, ha camminato per 10 minuti e poi ha eseguito per altri 10 minuti. Anche altre app possono segnalare correttamente l'attività esaminando i dati relativi al segmento attività che hai inserito.

Per aggiungere dati di segmenti di attività a una sessione, crea un set di dati che contenga punti di tipo com.google.activity.segment. Ciascuno di questi punti rappresenta un intervallo di tempo continuo durante il quale l'utente ha eseguito un singolo tipo di attività.

L'esempio di corsa e camminata precedente richiedeva tre punti di attività: uno per correre nei primi 10 minuti, uno per camminare durante i 10 minuti successivi e uno per correre negli ultimi 10 minuti.

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

Leggere i dati sull'attività fisica utilizzando le sessioni

L'API Sessions ti consente di ottenere un elenco di sessioni dal negozio di fitness che soddisfano alcuni criteri. Ad esempio, puoi ottenere tutte le sessioni contenute in un intervallo di tempo o una sessione specifica in base al nome o all'ID. Puoi anche specificare se ti interessano le sessioni create dalla tua app o da qualsiasi app.

Per ottenere un elenco di sessioni che corrispondono ad alcuni criteri, devi prima creare un'istanza 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();

Quindi utilizza il metodo 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));

Leggere i dati relativi al sonno utilizzando le sessioni

Le sessioni di sonno vengono trattate come distinte dalle altre sessioni di attività. Per impostazione predefinita, le risposte di lettura contengono solo sessioni di attività, non sessioni di sonno.

Per includere le sessioni di sonno, utilizza il metodo includeSleepSessions quando crei il tuo SessionReadRequest. Per includere sia le attività sia le sessioni, utilizza includeSleepSessions e includeActivitySessions.

Mostra sessioni in altre app

Per mostrare agli utenti una visione più dettagliata di una determinata sessione in un'altra app, la tua app può richiamare un intent che contiene le informazioni relative alla sessione. Puoi specificare un'app specifica, ad esempio quella che ha creato la sessione. Oppure, nel caso in cui l'app che ha creato la sessione non sia installata sul dispositivo, puoi consentire a qualsiasi app in grado di mostrare l'attività di fitness di rispondere all'intenzione.

Per creare un intent per mostrare i dati di sessione su un'app diversa, utilizza la classe SessionsApi.ViewIntentBuilder:

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

Ricevere intent da altre app

Per registrare la tua app in modo da ricevere intent da altre app per salute e benessere, dichiara nel file manifest un filtro per intent simile a quello che segue:

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

Ogni intent che la tua app riceve da Google Fit è di una sola attività, ma puoi filtrare per più tipi MIME in un singolo filtro per intent. Il filtro per intent dell'app deve includere tutte le attività supportate dall'app.

Gli intent di fitness includono i seguenti extra:

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

Puoi ottenere dati da questi extra nel seguente modo:

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