세션으로 작업

세션은 사용자가 피트니스 활동을 하는 시간 간격을 나타냅니다. Sessions API를 사용하면 앱이 피트니스 저장소에 세션을 만들 수 있습니다.

사용자가 피트니스 활동을 시작하고 완료할 때 앱에 알리는 진행 중인 피트니스 활동의 경우 실시간으로 세션을 만들 수 있습니다.

피트니스 활동이 끝난 후 또는 Google 피트니스 외부에서 데이터 및 세션을 가져올 때 피트니스 저장소에 세션을 삽입할 수도 있습니다.

실시간으로 세션 만들기

진행 중인 피트니스 활동을 위한 세션을 만들려면 다음 단계를 완료하세요.

  1. RecordingClient.subscribe 메서드를 사용하여 피트니스 데이터를 구독합니다.

  2. 사용자가 피트니스 활동을 시작할 때 SessionsClient.startSession 메서드를 사용하여 세션을 시작합니다.

  3. 사용자가 피트니스 활동을 종료할 때 SessionsClient.stopSession 메서드를 사용하여 세션을 중지합니다.

  4. 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 객체의 이름입니다.

피트니스 스토어에 세션 삽입

이전에 수집한 데이터가 포함된 세션을 삽입하려면 다음 단계를 따르세요.

  1. 시간 간격과 기타 필수 정보를 지정하는 Session 객체를 만듭니다.

  2. 세션으로 SessionInsertRequest을 만듭니다.

  3. 원하는 경우 데이터 세트를 추가하고 데이터 포인트를 집계합니다.

  4. 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 피트니스의 활동 세그먼트 데이터는 지정된 시간 간격 동안 사용자가 수행하는 피트니스 활동을 나타냅니다. 활동 세그먼트 데이터는 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 메서드를 사용합니다. 활동과 세션을 모두 포함하려면 includeSleepSessionsincludeActivitySessions를 모두 사용하세요.

다른 앱의 세션 표시

앱에서 사용자에게 다른 앱의 특정 세션을 자세히 보여주려면 세션 정보가 포함된 인텐트를 호출하면 됩니다. 세션을 만든 앱과 같은 특정 앱을 지정할 수 있습니다. 또는 세션을 만든 앱이 기기에 설치되어 있지 않은 경우 피트니스 활동을 표시할 수 있는 모든 앱이 인텐트에 응답하도록 허용할 수 있습니다.

다른 앱에 세션 데이터를 표시할 인텐트를 만들려면 다음과 같이 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 피트니스에서 수신하는 각 인텐트는 하나의 활동에만 속하지만 단일 인텐트 필터에서 여러 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());
    }
}