세션은 사용자가 피트니스 활동을 하는 동안의 시간 간격을 나타냅니다. Sessions API를 사용하면 앱에서 피트니스 저장소에 세션을 만들 수 있습니다.
사용자가 피트니스 활동을 시작하고 완료할 때 앱에 알림을 보내는 지속적인 피트니스 활동의 경우 실시간으로 세션을 만들 수 있습니다.
피트니스 활동이 끝난 후 또는 Google 피트니스 외부에서 데이터와 세션을 가져올 때 피트니스 저장소에 세션을 삽입할 수도 있습니다.
실시간으로 세션 만들기
진행 중인 피트니스 활동에 관한 세션을 만들려면 다음 단계를 완료하세요.
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) }
자바
// 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) }
자바
// 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()
자바
// 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) }
자바
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
유형의 점이 포함된 데이터 세트를 만드세요. 이러한 각 점은 사용자가 단일 활동 유형을 수행하는 연속적인 시간 간격을 나타냅니다.
이전의 달리기 및 걷기 예시에는 활동 세그먼트 지점 3개가 필요합니다. 하나는 첫 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()
자바
// 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()
자바
// 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) }
자바
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)
자바
// 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) } }
자바
@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()); } }