모바일의 Recording API를 사용하면 앱이 걸음 수 데이터를 가져오는 워치 밴드와 마찬가지로 배터리 효율적인 방식으로 휴대기기에서 걸음 수를 기록할 수 있습니다. 이 API는 계정이 없습니다. 즉, 서비스를 사용하기 위해 Google 계정이 필요하지 않으며 데이터가 기기에 저장됩니다.
이 가이드에서는 건강/피트니스 환경에서 모바일에서 Recording API를 사용하는 방법을 보여줍니다.
예시는 GitHub의 모바일의 녹음 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")
}
Groovy 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)
}
Read and Process Fitness Data
구독이 완료되면 readData
메서드를 사용하여 데이터를 요청합니다. 그런 다음 다음 코드 스니펫과 같이 LocalDataReadRequest
를 만들어 결과 LocalDataSet
에서 LocalDataPoints를 가져올 수 있습니다.
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)
}