Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

🛠 Wear + Phone Altitude 동기화 & 설정화면 컴파일 오류 해결 요약

Billcorea 2025. 12. 1. 15:20
반응형

 

 

🛠 Wear + Phone Altitude 동기화 & 설정화면 컴파일 오류 해결 요약

워치이미지

 

개요 (Intro)

  • 오늘의 목표: 고도(Altitude) 측정 데이터 Wear→Phone 실시간 전송, 설정 화면에 단위/최근 갱신 시각 표시, SegmentedButton 컴파일 오류 해결
  • 배경: 기존 Steps 동기화는 동작하지만 고도 및 제스처(큰절) 인식 흐름 표시 요소 부족 + Material3 실험 API로 인해 빌드 실패
  • 사용 기술 스택: Kotlin, Jetpack Compose (Material3), Hilt, Health Connect, Health Services, Wearable Data/Message API, Sensor API
📅 날짜: 2025.12.01
🎯 목표: Altitude 실시간 반영 + SettingsScreen 안정화 + Wear/Phone namespace 정렬
🧰 기술: Kotlin, Compose, Hilt, Wear OS, Health Connect, Sensors, DataClient/MessageClient

문제 정의 (Problem / Motivation)

  • SettingsScreen에서 Material3 SegmentedButton 관련 심볼(Unresolved reference)로 컴파일 실패
  • Wear AVD에서 가속도/고도 센서 이벤트가 들어오지 않아 실측값 테스트 어려움
  • 고도 전송 이후 Phone UI에서 최근 갱신 시각을 안정적으로 식별할 상태 변수가 부재
  • Namespace / ApplicationId를 Phone과 Wear 간 통일 필요 (데이터 교환 및 추적 용이)
// (오류 예시) SegmentedButtonRow 미존재로 컴파일 실패
// implementation(libs.androidx.compose.material3) 버전에서 제공 안 됨
SegmentedButtonRow { /* ... */ } // Unresolved reference

해결 과정 (How I Solved It)

  • 고도 수신을 위한 ViewModel 상태 추가: altitudeMeters, altitudeTimestamp (StateFlow)
  • WearDataSyncManager.Listener에 onAltitudeUpdate(...) 콜백 정의하여 Phone 측 반영
  • SettingsScreen: 실험적 SegmentedButton 제거 → Button + OutlinedButton 토글 구현
  • 최근 갱신 시각: altitudeTimestamp 우선, 없으면 마지막 steps 페이로드 timestamp 폴백
  • 에뮬레이터 한계 대응: 실제 센서 없을 경우 ‘-’ 출력 및 Mock 옵션 향후 추가 계획 수립
  • Wear 모듈 build.gradle.kts에 compose.compiler 및 namespace=phone 앱 동일 값 적용
// ViewModel 고도 상태 및 리스너 발췌
private val _altitudeMeters = MutableStateFlow<Double?>(null)
val altitudeMeters: StateFlow<Double?> = _altitudeMeters
private val _altitudeTimestamp = MutableStateFlow<Long?>(null)
val altitudeTimestamp: StateFlow<Long?> = _altitudeTimestamp

wearDataSyncManager.listener = object : WearDataSyncManager.Listener {
    override fun onAltitudeUpdate(altitudeMeters: Double, timestamp: Long, source: String) {
        _altitudeMeters.value = altitudeMeters
        _altitudeTimestamp.value = timestamp
    }
    // ... steps, gesture 등 다른 콜백
}
// SettingsScreen 고도 단위 토글 (Button / OutlinedButton)
Row {
    Text("고도 단위: ")
    if (unit == "m") {
        Button(onClick = { unit = "m" }) { Text("m") }
        OutlinedButton(onClick = { unit = "ft" }) { Text("ft") }
    } else {
        OutlinedButton(onClick = { unit = "m" }) { Text("m") }
        Button(onClick = { unit = "ft" }) { Text("ft") }
    }
}

결과 (Result)

  • 빌드 실패 원인이었던 SegmentedButton 관련 심볼 제거 후 컴파일 성공
  • 고도 실시간 값 및 최근 갱신 시각 UI 노출 로직 정상 반영 (실기기 테스트 필요)
  • Wear/Phone 동일 namespace & applicationId 적용으로 코드/로그 추적 용이
  • 제스처 인식 시작/종료 UI 명확해져 사용자 경험 개선
✅ SettingsScreen 컴파일 오류 제거
✅ Altitude 실시간 상태 흐름(StateFlow) 구축
⚠️ AVD 센서 미동작: 실제 기기 테스트 대기

느낀 점 / 회고 (Reflection)

  • 실험적 Compose API는 버전 호환을 먼저 확인해야 낭비 시간을 줄일 수 있다.
  • 센서 기반 기능은 에뮬레이터 한계가 커서 Mock/실기기 병행 전략이 필수.
  • 데이터 전송 시 timestamp를 분리 관리하면 UI 표시/디버깅이 훨씬 명확해진다.
  • 단위 토글을 단순화하니 유지보수성과 접근성이 모두 향상되었다.

참고자료 (References)


다음 개선 아이디어

  • Mock 센서 토글 추가 (AVD에서 흐름 검증)
  • Altitude smoothing (이동평균) & 최소 전송 간격 조정
  • 큰절 인식 정확도 향상을 위한 패턴 분석/버퍼링
  • Locale 안전한 숫자 포맷 적용 (String.format(Locale,...))
반응형