모바일용 Recording API

모바일 앱의 Recording API를 사용하면 휴대기기에서 걸음 수를 기록할 수 있습니다. 배터리 효율적인 방식으로 진행되고 있습니다. 이 API는 계정이 없으므로 서비스를 사용하기 위한 Google 계정이 필요하며 데이터는 기기에 저장됩니다.

이 가이드에서는 건강 및 건강 상태의 휴대기기로 Recording API를 사용하는 방법을 설명합니다. 전념하고 있습니다.

주요 세부정보

모바일의 Recording API에는 몇 가지 주목할 만한 기능이 있습니다.

  • 녹음 구독이 시작되거나 갱신되면 (최대 10일간)에 액세스할 수 있습니다.
  • 활성 상태인 구독이 있어야만 데이터를 사용할 수 있습니다. 정기 결제인 경우 unsubscribe를 호출하여 삭제하면 수집된 걸음 수 데이터에 액세스할 수 없습니다.

데이터 유형

모바일의 Recording API는 다음 데이터 유형을 기록할 수 있습니다.

시작하기

시작하려면 build.gradle 파일에 다음 종속 항목을 추가합니다.

Kotlin DSL

plugin {
  id("com.android.application")
}

...

dependencies {
  implementation("com.google.android.gms:play-services-fitness:21.2.0")
}

그루비 DSL

apply plugin: 'com.android.application'

...

dependencies {
  implementation 'com.google.android.gms:play-services-fitness:21.2.0'
}

권한 요청

모바일에서 Recording API를 사용하여 데이터를 기록하려면 앱에서 다음 권한이 있어야 합니다.

  • android.permission.ACTIVITY_RECOGNITION

Play 서비스 버전 확인 실행

모바일에서 Recording API를 사용하려면 사용자에게 Google Play 서비스가 있어야 합니다. LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE(으)로 업데이트되었습니다. 여기에서 isGooglePlayServicesAvailable 메서드 사용:

val hasMinPlayServices = isGooglePlayServicesAvailable(context, LocalRecordingClient.LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE)

if(hasMinPlayServices != ConnectionResult.SUCCESS) {
  // Prompt user to update their device's Google Play services app and return
}

// Continue with Recording API functions

그러지 않고 사용자의 Google Play 서비스 버전이 너무 낮으면 시스템이 ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED 발생 예외가 인정됩니다.

피트니스 데이터 구독

걸음 수 데이터의 백그라운드 수집을 요청하려면 subscribe 메서드에 전달합니다.

val localRecordingClient = FitnessLocal.getLocalRecordingClient(this)
// Subscribe to steps data
localRecordingClient.subscribe(LocalDataType.TYPE_STEP_COUNT_DELTA)
  .addOnSuccessListener {
    Log.i(TAG, "Successfully subscribed!")
  }
  .addOnFailureListener { e ->
    Log.w(TAG, "There was a problem subscribing.", e)
  }

피트니스 데이터 읽기 및 처리

구독하면 readData 메서드를 사용하여 데이터를 요청합니다. 그런 다음 다음과 같이 결과 LocalDataSet에서 LocalDataPoint를 가져옵니다. 다음 코드와 같이 LocalDataReadRequest를 만듭니다. snippet:

val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusWeeks(1)
val readRequest =
  LocalDataReadRequest.Builder()
    // The data request can specify multiple data types to return,
    // effectively combining multiple data queries into one call.
    // This example demonstrates aggregating only one data type.
    .aggregate(LocalDataType.TYPE_STEP_COUNT_DELTA)
    // Analogous to a "Group By" in SQL, defines how data should be
    // aggregated. bucketByTime allows bucketing by time span.
    .bucketByTime(1, TimeUnit.DAYS)
    .setTimeRange(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
    .build()

  localRecordingClient.readData(readRequest).addOnSuccessListener { response ->
    // The aggregate query puts datasets into buckets, so flatten into a
    // single list of datasets.
    for (dataSet in response.buckets.flatMap { it.dataSets }) {
      dumpDataSet(dataSet)
    }
  }
  .addOnFailureListener { e ->
    Log.w(TAG,"There was an error reading data", e)
  }

fun dumpDataSet(dataSet: LocalDataSet) {
  Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
  for (dp in dataSet.dataPoints) {
    Log.i(TAG,"Data point:")
    Log.i(TAG,"\tType: ${dp.dataType.name}")
    Log.i(TAG,"\tStart: ${dp.getStartTime(TimeUnit.HOURS)}")
    Log.i(TAG,"\tEnd: ${dp.getEndTime(TimeUnit.HOURS)}")
    for (field in dp.dataType.fields) {
      Log.i(TAG,"\tLocalField: ${field.name.toString()} LocalValue: ${dp.getValue(field)}")
    }
  }
}

LocalRecordingClient는 데이터 컬렉션을 지속적으로 업데이트합니다. 다음과 같은 작업을 할 수 있습니다. readData를 사용하여 언제든지 최신 수치를 가져올 수 있습니다.

LocalRecordingClient는 최대 10일간의 데이터를 저장합니다. 감소하는 손실 위험이 있으므로 WorkManager를 사용하여 만들 수 있습니다.

피트니스 데이터 수신 거부

리소스를 확보하려면 구독 취소를 해야 합니다. 앱에서 더 이상 필요하지 않은 센서 데이터 수집 받는사람 구독을 취소하려면 unsubscribe 메서드를 사용합니다.

val localRecordingClient = FitnessLocal.getLocalRecordingClient(this)
// Unsubscribe from steps data
localRecordingClient.unsubscribe(LocalDataType.TYPE_STEP_COUNT_DELTA)
  .addOnSuccessListener {
    Log.i(TAG, "Successfully unsubscribed!")
  }
  .addOnFailureListener { e ->
    Log.w(TAG, "There was a problem unsubscribing.", e)
  }