セッションは、ユーザーがフィットネス アクティビティを行っている時間間隔を表します。Sessions API を使用すると、アプリはフィットネス ストアでセッションを作成できます。
進行中のフィットネス アクティビティで、フィットネス アクティビティの開始時と終了時にユーザーがアプリに通知する場合は、セッションをリアルタイムで作成できます。
フィットネス アクティビティが終了した後や、Google Fit 以外からデータやセッションをインポートしたときに、フィットネス ストアにセッションを挿入することもできます。
リアルタイムでセッションを作成する
進行中のフィットネス アクティビティのセッションを作成する手順は次のとおりです。
RecordingClient.subscribe
メソッドを使用して、フィットネス データに登録します。ユーザーがフィットネス アクティビティを開始したら、
SessionsClient.startSession
メソッドを使用してセッションを開始します。ユーザーがフィットネス アクティビティを終了したら、
SessionsClient.stopSession
メソッドを使用してセッションを停止します。RecordingClient.unsubscribe
メソッドを使用して、不要になったフィットネス データの登録を解除します。
セッションを開始する
アプリでセッションを開始するには、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
タイプのポイントを含むデータセットを作成します。これらの各ポイントは、ユーザーが単一のアクティビティ タイプを実行した連続した時間間隔を表します。
上記のランニングとウォーキングの例では、3 つのアクティビティ セグメント ポイントが必要です。1 つは最初の 10 分間のランニング用、1 つは次の 10 分間のウォーキング用、もう 1 つは最後の 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 から受け取る各インテントは 1 つのアクティビティのみが含まれますが、1 つのインテント フィルタで複数の 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()); } }