「工作階段」代表使用者執行健身活動的時間間隔。工作階段 API 可讓應用程式在健身商店中建立工作階段。
如果是持續進行的健身活動,當使用者開始和完成健身活動時,系統會通知您的應用程式,您可以即時建立時段。
您也可以在健身活動結束後,或從 Google Fit 以外的來源匯入資料和時段時,將時段插入健身商店。
即時建立工作階段
如要為進行中的健身活動建立課程,請完成下列步驟:
在使用者啟動健身活動時,使用
SessionsClient.startSession
方法啟動工作階段。使用者結束健身活動時,使用
SessionsClient.stopSession
方法停止工作階段。
啟動工作階段
如要在應用程式中啟動工作階段,請使用 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));
停止工作階段
如要停止應用程式中的工作階段,請使用 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));
產生的工作階段包含下列參數:
開始時間:應用程式呼叫
SessionsClient.startSession
方法的時間。結束時間:應用程式呼叫
SessionsClient.stopSession
方法的時間。名稱:您傳遞至
SessionsClient.startSession
的Session
物件名稱。
在健身商店中插入課程
如要插入包含先前所收集資料的工作階段,請按照下列步驟操作:
建立
Session
物件來指定時間間隔和其他必要資訊。使用工作階段建立
SessionInsertRequest
。您也可以選擇新增資料集和匯總資料點。
使用
SessionsClient.insertSession
方法插入工作階段。
插入課程
如要將包含工作階段中繼資料的健身資料插入使用者的健身記錄,請先建立 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();
SessionInsertRequest
類別提供便利的方法,可將資料插入健身記錄,並在與 SessionsClient.insertSession
相同的呼叫中建立工作階段。如果有資料集,系統會比照您先呼叫 HistoryClient.insertData
方法的方式插入資料集,然後再建立工作階段。
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));
插入活動區隔
Google Fit 中的活動區隔資料會顯示使用者在特定時間間隔的健身活動。活動區隔資料的類型為 com.google.activity.segment
(TYPE_ACTIVITY_SEGMENT
),特別適合用於健身期間的暫停情形。
舉例來說,如果您使用 Session.Builder.setActivity()
方法建立 30 分鐘的跑步工作階段,但使用者需要花 10 分鐘的時間,應用程式將無法正確顯示使用者已跑 30 分鐘。只要應用程式可偵測使用者是否在走路或跑步,活動區隔資料就能指出使用者跑了 10 分鐘,步行 10 分鐘,再多跑步 10 分鐘。其他應用程式也可以查看您插入的活動區隔資料,藉此正確回報活動。
如要將活動區隔資料新增至時段,請建立包含 com.google.activity.segment
類型點的資料集。每個點都代表使用者執行單一活動類型的連續時間間隔。
上一個跑步和步行範例需要三個活動區隔點:一個在前 10 分鐘跑步、一個在接下來 10 分鐘內行走,另一個則用於最後 10 分鐘跑步。
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();
使用時段讀取健身資料
Sessions API 可讓您從健身商店取得符合某些條件的工作階段清單。例如,您可以取得某一時間間隔包含的所有工作階段,或按名稱或 ID 取得特定時段。您還可以指定想瞭解由應用程式還是任何應用程式建立的工作階段。
如要取得符合特定條件的工作階段清單,請先建立 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();
然後使用 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));
使用時段讀取睡眠資料
睡眠時段會與其他活動時段不同。根據預設,讀取回應僅包含活動時段,不含睡眠時段。
如要納入睡眠時段,請在建立 SessionReadRequest
時使用 includeSleepSessions
方法。如要同時納入活動和時段,請同時使用 includeSleepSessions
和 includeActivitySessions
。
顯示其他應用程式中的工作階段
如要向使用者顯示更多應用程式中特定工作階段的詳細資料,應用程式可以叫用含有工作階段資訊的意圖。您可以指定特定應用程式,例如建立工作階段的應用程式。或者,如果建立工作階段的應用程式未安裝在裝置上,您可以允許任何可顯示健身活動的應用程式來回應意圖。
如要建立意圖以顯示其他應用程式的工作階段資料,請使用 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);
接收其他應用程式的意圖
如果想註冊應用程式以接收其他健康與保健應用程式的意圖,請在資訊清單中宣告類似下列內容的意圖篩選器:
<intent-filter>
<action android:name="vnd.google.fitness.VIEW"/>
<data android:mimeType="vnd.google.fitness.session/running"/>
</intent-filter>
應用程式從 Google Fit 接收的每個意圖都只是一項活動,但您可以在單一意圖篩選器中篩選多個 MIME 類型。應用程式的意圖篩選器必須包含應用程式支援的所有活動。
健身意圖包括下列額外項目:
vnd.google.gms.fitness.start_time
vnd.google.gms.fitness.end_time
vnd.google.gms.fitness.session
您可以按照下列步驟從這些額外項目中取得資料:
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()); } }