[Android] Google Fitness API
개요
Google Fitness API는 사용자의 건강 및 활동(운동) 정보를 기록하고 관리하는 것을 서비스입니다.
모바일 앱을 통해 사용 가능하며, 반드시 구글 계정을 연동해야합니다.
기록되는 데이터는 클라우드 공간(Google Fitness Store)에 저장되며, 다른 기기(기존에 연동한 계정이면)에서도 값을 확인할 수 있습니다.
권한
사용자의 신체 활동 정보에 엑세스하는 권한
Android 10 (API level 29) 이상부터는 권한 동의 필요 (이하는 권한 자동으로 부여)
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
라이브러리
build.gradle에서 Google Play Service Client 라이브러리 추가
plugin {
id("com.android.application")
}
implementation 'com.google.android.gms:play-services-fitness:20.0.0'
implementation 'com.google.android.gms:play-services-auth:19.0.0'
OAuth client ID 발급
- [구글 클라우드 플랫폼](https://console.cloud.google.com/) 에서 프로젝트를 생성한다
- Fitness API 사용 설정
- OAuth 동의 화면 구성
- OAuth client ID 발급 (이름, 패키지 이름, SHA-1 인증서 디지털 지문 등록)
SHA-1 인증서 디지털 지문 조회 방법
Terminal 창에서 아래 명령어 입력하면 인증서 정보 나옴
keytool -list -v -keystore "키 경로 지정"(예시 ~/.android/debug.keystore) -alias androiddebugkey -storepass android -keypass android
테스트 시 debug 인증서 정보 사용하고,
배포 시 realse 인증서 정보의 지문으로 변경해야함
테스트 시 실행 과정
1. Api level 29 이상이면 권한(신체 활동 정보에 대한)을 받는다
2. 조회하고자 하는 데이터 타입 설정
val fitnessOptions: FitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
.addDataType(DataType.TYPE_STEP_COUNT_DELTA)
.addDataType(DataType.TYPE_CALORIES_EXPENDED)
.addDataType(DataType.TYPE_DISTANCE_DELTA)
.addDataType(DataType.TYPE_MOVE_MINUTES)
.addDataType(DataType.TYPE_HEIGHT)
.addDataType(DataType.TYPE_WEIGHT)
.build()
3. Google OAuth 권한을 받는다
GoogleSignIn.requestPermissions(
requireActivity(),
FITNESS_CODE,
getGoogleAccount(), fitnessOptions
)
OAuth client ID를 제대로 발급 받았다면 구글 로그인 페이지 후 OAuth 권한 요청 페이지로 이동 할 것이다
4. Fitness 데이터 조회
데이터 조회는 Fitness.getHistoryClient()를 사용하며 DataReadRequest.Builder()를 통해 읽고자 하는 데이터의 타입 및 기간을 미리 지정한다.
아래의 메서드는 조회하고자 하는 기간(단위 milliseconds)을 입력하면 걸음 수, 이동 거리, 이동 시간, 소모된 칼로리를 조회하는 예시이다.
// 걸음 수 조회 예시
private fun readSteps(startTime: Long, endTime: Long) {
val dataSource = DataSource.Builder()
.setAppPackageName("com.google.android.gms")
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setType(DataSource.TYPE_DERIVED)
.setStreamName("estimated_steps")
.build()
val request = DataReadRequest.Builder()
.aggregate(dataSource)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build()
Fitness.getHistoryClient(context, getGoogleAccount())
.readData(request)
.addOnSuccessListener { response ->
response.buckets.map { bucket ->
val dataSetStep = bucket.getDataSet(DataType.TYPE_STEP_COUNT_DELTA)
dataSetStep?.let {
var dailyStep = 0
it.dataPoints.map { dataPoint ->
dailyStep += dataPoint.getValue(Field.FIELD_STEPS).asInt()
}
Logger.d("Daily step: $dailyStep")
}
}
}
.addOnFailureListener { e ->
Logger.d("There was a problem getting the step count.", e)
}
}
// 이동 거리, 이동 시간, 소모된 칼로리 조회 예시
private fun readTimeDistanceCalories(startTime: Long, endTime: Long) {
val request = DataReadRequest.Builder()
.read(DataType.TYPE_DISTANCE_DELTA)
.read(DataType.TYPE_MOVE_MINUTES)
.read(DataType.AGGREGATE_CALORIES_EXPENDED)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build()
Fitness.getHistoryClient(context, getGoogleAccount())
.readData(request)
.addOnSuccessListener { response ->
response.buckets.map { bucket ->
val dataSetDistance = bucket.getDataSet(DataType.TYPE_DISTANCE_DELTA)
val dataSetMoveMinutes = bucket.getDataSet(DataType.TYPE_MOVE_MINUTES)
val dataSetCalories = bucket.getDataSet(DataType.AGGREGATE_CALORIES_EXPENDED)
var dailyDistance = 0.0
var dailyCalories = 0.0
dataSetDistance?.let {
it.dataPoints.map { dataPoint ->
dailyDistance += dataPoint.getValue(Field.FIELD_DISTANCE).asFloat()
}
Logger.d("Daily distance: $dailyDistance")
}
dataSetMoveMinutes?.let {
Logger.d("Daily time: ${it.dataPoints.size}")
}
dataSetCalories?.let {
if (dailyDistance != 0.0) {
it.dataPoints.map { dataPoint ->
dailyCalories += dataPoint.getValue(Field.FIELD_CALORIES).asFloat()
}
}
Logger.d("Daily Calories: $dailyCalories")
}
}
}
}
5. 테스트 결과
Google Fitness App | 위에서 구현한 Test App | 특이 사항 | |
걸음 수 | 4413 | 4413 | - |
이동 거리 | 2.39 km | 2925 meter | - |
이동 시간 | 59 min | 59 min | - |
칼로리 | 1810 Cal | 1810 Cal | 오늘 기준 현재 시간 기준으로 계산해야함 (Google Fitness App은 30초 단위로 칼로리 계산) |
위에서 테스트한 API 외에도 영양정보, 물 섭취량, 수면기록도 관리할 수 있다.
참고