Sessions represent a time interval during which users perform a fitness activity. The Sessions API enables your app to create sessions in the fitness store using real time data or data you previously collected using the Sensors API or outside Google Fit.
For ongoing fitness activities where the user notifies your app when they start and finish a fitness activity, you can create sessions in real time.
You can also insert a session into the fitness store after a fitness activity finished, or when you are importing data and sessions from outside Google Fit.
Create sessions in real time
To create sessions for ongoing fitness activities:
- Subscribe to fitness data with the
RecordingClient.subscribe
method. - Start a session with the
SessionsClient.startSession
method when the user initiates the fitness activity. - Stop the session with the
SessionsClient.stopSession
method when the user ends the fitness activity. - Unsubscribe from fitness data you are no
longer interested in with the
RecordingClient.unsubscribe
method.
Start a session
To start a session in your app, use the
SessionsClient.startSession
method:
// 1. Subscribe to fitness data (see Recording Fitness Data) // 2. Create a session object // (provide a name, identifier, description, activity and start time) val session = Session.Builder() .setName(sessionName) .setIdentifier(identifier) .setDescription(description) .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) }
Stop a session
To stop a session in your app, use the
SessionsClient.stopSession
method:
// 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) }
The resulting session has these parameters:
- Start time: The time when your app called the
SessionsClient.startSession
method. - End time: The time when your app called the
SessionsClient.stopSession
method. - Name: The name in the
Session
object that you pass toSessionsClient.startSession
.
Insert sessions in the fitness store
To insert sessions with data you previously collected:
- Create a
Session
object specifying a time interval and other required information. - Create a
SessionInsertRequest
with the session and optionally add datasets and aggregate data points. - Insert the session with the
SessionsClient.insertSession
. method.
Insert a session
To insert fitness data with session metadata into the user's fitness history, first create a
SessionInsertRequest
instance:
// 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 insertRequest = SessionInsertRequest.Builder() .setSession(session) // Optionally add DataSets for this session. .addDataSet(dataset) .build()
The
SessionInsertRequest
class provides convenience methods to insert data into the fitness
history and create a session in the same call to
SessionsClient.insertSession
,
since this is a common use case when importing data. The datasets (if any) are inserted as if you
had called the
HistoryClient.insertData
method first, and then the session is created.
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) }
Insert activity segments
Activity segment data in Google Fit indicates what fitness activity users are performing in a
given time interval. Activity segment data is of type com.google.activity.segment
(TYPE_ACTIVITY_SEGMENT
)
and is particularly useful to support pauses during workouts.
For example, if you create a 30-minute running session with the
Session.Builder.setActivity()
method but the user takes a 10-minute break in between, your app will incorrectly show that
the user run for 30 minutes. Provided your app can detect whether the user was walking or running,
activity segment data lets your app indicate that the user was running for 10 minutes, walking for
10 minutes, and running for 10 minutes. Other apps can also report the activity correctly by
looking at the activity segment data you inserted.
To add activity segment data to a session, you create an additional dataset that contains points of
type com.google.activity.segment
. Each of these points represents a continuous time interval during
which the user was performing a single activity type. The previous running and walking example would
require three activity segment points: one for running during the first 10 minutes, one for walking
during the next 10 minutes, and one for running during the final 10 minutes.
// Create a DataSet of ActivitySegments to indicate the runner took a 10-minute walk in the // middle of the 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()
Read fitness data using sessions
The Sessions API lets you obtain a list of sessions from the fitness store that match some criteria. For example, you can obtain all the sessions contained in a time interval for a particular data, or get a particular session by name or ID. You can also specify if you are interested in sessions created by your app or by any app.
To obtain a list of sessions that match some criteria, first create a
SessionReadRequest
instance:
// Set a start and end time for our query, using a start time of 1 week before this moment. 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()
Then use the
SessionsClient.readSession
method:
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) }
Read sleep data using sessions
Sleep sessions are treated as distinct from other activity sessions. By default, read responses contains only activity sessions, not sleep sessions.
To include sleep sessions, use the includeSleepSessions
method when building your SessionReadRequest
. To include both activities and
sessions use both includeSleepSessions
and includeActivitySessions
.
Show sessions in other apps
To show users a more detailed view of a particular session in a different app, your app can fire an intent with the session information. You can specify a particular app (like the app that created the session), or you can let any app that can show data from that fitness activity respond to the intent if the app that created the session is not installed on the device. Your app can also register an intent filter to display detailed session data from some activity types.
To create an intent to show session data on a different app, use the
SessionsApi.ViewIntentBuilder
class:
// Pass your activity object to the constructor val intent = SessionsApi.ViewIntentBuilder(this) .setPreferredApplication("com.example.someapp") // optional .setSession(session) .build() // Fire the intent startActivity(intent)
To register a listener in your app for the types of session data your app can show, include an intent filter like the following for your activity in the manifest file:
<activity android:name="com.example.ViewSessionActivity" android:exported="true">
<intent-filter>
<action android:name="vnd.google.fitness.VIEW" />
<data android:mimeType="vnd.google.fitness.session/biking" />
<data android:mimeType="vnd.google.fitness.session/running" />
</intent-filter>
</activity>
Session broadcast intents
Google Fit broadcasts intents when any app starts or stops recording a session on behalf of the user. Fitness apps can register a listener to receive these intents.
Session start intents
When you start recording a session, Google Fit broadcasts an intent with:
- The action set to
ACTION_SESSION_START
- The type set to
MIME_ACTIVITY_TYPE_PREFIX/<activity_type>
- The
EXTRA_SESSION
extra set to the new session
activity_type is the constant string value for the activity associated with this session (see
the API reference for
FitnessActivities
).
To register a listener in your app for session start intents with activity type
RUNNING
,
add the following to your manifest file:
Session end intents
When an app stops recording a session, Google Fit broadcasts an intent with:
- The action set to
ACTION_SESSION_END
- The type set to
MIME_ACTIVITY_TYPE_PREFIX/<activity_type>
- The
EXTRA_SESSION
extra set to the session
To register a listener in your app for session end intents with activity type
RUNNING
,
add the following your manifest file: