본문 바로가기
Android

[Android] TrustedTime API: 앱에서 신뢰할 수 있는 시간 관리 방법

by LoseyKim 2025. 2. 19.
Google Developer 사이트를 보다 흥미로운 새 API를 발견하여 가져왔습니다.
이 글은 제 개인적인 창작물이 아니라, 구글 블로그에 게재된 내용을 바탕으로 번역하여 작성한 것입니다.

 

앱 개발 시 일정 관리, 이벤트 스케줄링, 거래 기록, 보안 등 다양한 기능에 있어 정확한 시간이 필수적입니다. 하지만 기기의 시간을 그대로 사용하면 사용자가 이를 손쉽게 변경할 수 있어 여러 문제가 발생할 수 있죠. 이를 해결하기 위해 Google의 인프라를 활용해 기기의 시간 조작 여부와 관계없이 항상 정확한 시간을 제공하는 TrustedTime API를 소개합니다.

TrustedTime API란?

TrustedTime API는 Google의 안전한 서버와 주기적으로 동기화하여 앱이 네트워크 요청 없이도 항상 최신의 정확한 시간을 확인할 수 있도록 도와줍니다. 게다가 기기의 시계 오차(드리프트)를 계산해 네트워크 동기화 간의 시간 차이를 예측할 수 있어, 앱에서 발생할 수 있는 시간 관련 오류를 효과적으로 방지할 수 있습니다.

왜 정확한 시간이 중요한가?

앱이 기기의 기본 시간을 사용하면 다음과 같은 문제가 발생할 수 있습니다:

  • 데이터 순서의 혼란: 시간 순서대로 기록되어야 하는 이벤트들이 제대로 정렬되지 않아 데이터 일관성이 무너질 수 있습니다.
  • 보안 취약점: 일회용 비밀번호나 시간제한 기능 등 시간 기반 보안 메커니즘이 제대로 작동하지 않을 위험이 있습니다.
  • 일정 관리 오류: 캘린더나 리마인더 앱에서 잘못된 시간이 기록되면 사용자에게 혼란을 줄 수 있습니다.
  • 시계 오차: 기기 내부 시계는 온도, 배터리 상태, 절전 모드 등 다양한 요인에 의해 미세한 오차가 발생할 수 있습니다. TrustedTime API는 이러한 오차 범위를 함께 제공하여 보완합니다.
  • 기기간 시간 불일치: 여러 기기를 사용하는 환경에서 각 기기의 시간이 다르면 협업이나 멀티플레이어 게임 등에서 문제가 생길 수 있습니다.
  • 불필요한 네트워크 요청: 매번 NTP 서버에 요청할 필요 없이 주기적으로 동기화된 시간을 사용해 전력과 데이터 사용을 줄일 수 있습니다.

TrustedTime API의 활용 사례

TrustedTime API는 다양한 분야에서 앱의 신뢰성과 보안을 강화할 수 있는 솔루션입니다. 주요 활용 사례는 다음과 같습니다

  • 금융 앱: 오프라인 상태에서도 거래 시간의 정확성을 유지하여 부정 거래나 분쟁을 예방합니다.
  • 게임: 사용자가 게임 시간을 조작해 부당한 이득을 얻는 것을 방지하여 공정한 플레이를 보장합니다.
  • 한정 이벤트: 기기 시간에 영향을 받지 않고 이벤트나 프로모션의 종료 시간을 정확하게 관리할 수 있습니다.
  • 전자 상거래: 주문 처리 및 배송 시간을 정확하게 기록하여 사용자 신뢰를 높입니다.
  • 콘텐츠 라이선싱: 대여나 구독 등 콘텐츠 사용 기간을 철저하게 관리할 수 있습니다.
  • IoT 기기: 여러 기기의 시간을 동기화해 데이터 기록 및 제어의 일관성을 유지합니다.
  • 생산성 앱: 오프라인 상태에서도 클라우드 문서의 변경 시간을 정확하게 기록할 수 있습니다.

TrustedTime API 시작하기

TrustedTime API는 Google Play 서비스를 기반으로 구축되어 대부분의 Android 앱에 손쉽게 통합할 수 있습니다. 아래 단계별 가이드를 통해 시작해 보세요.

1. 앱 실행 시 TrustedTimeClient 초기화 (선택)

앱이 실행될 때, 예를 들어 Application 클래스의 `onCreate()` 메서드에서 `TrustedTimeClient`를 초기화하면 됩니다. 아래는 Hilt를 사용한 의존성 주입 예제입니다.

// TrustedTimeClientAccessor.kt
import com.google.android.gms.tasks.Task
import com.google.android.gms.time.TrustedTimeClient

interface TrustedTimeClientAccessor {
  fun createClient(): Task<TrustedTimeClient>
}
// TrustedTimeModule.kt
@Module
@InstallIn(SingletonComponent::class)
class TrustedTimeModule {
  @Provides
  fun provideTrustedTimeClientAccessor(
    @ApplicationContext context: Context
  ): TrustedTimeClientAccessor {
    return object : TrustedTimeClientAccessor {
      override fun createClient(): Task<TrustedTimeClient> {
        return TrustedTime.createClient(context)
      }
    }
  }
}

2. 앱 초기화 시 클라이언트 설정

// TrustedTimeDemoApplication.kt
@HiltAndroidApp
class TrustedTimeDemoApplication : Application() {

  @Inject
  lateinit var trustedTimeClientAccessor: TrustedTimeClientAccessor

  var trustedTimeClient: TrustedTimeClient? = null
    private set

  override fun onCreate() {
    super.onCreate()
    trustedTimeClientAccessor.createClient().addOnCompleteListener { task ->
      if (task.isSuccessful) {
        // 클라이언트 저장
        trustedTimeClient = task.result
      } else {
        // 오류 처리 (나중에 재시도 가능)
        val exception = task.exception
      }
    }
    // Kotlin Coroutine을 사용하려면 await() 메서드를 활용하세요.
    // 자세한 내용은 https://developers.google.com/android/guides/tasks#kotlin_coroutine 참고
  }
}

의존성 주입을 사용하지 않는다면, TrustedTime.createClient(context)를 호출하면 됩니다.

3. 앱 내에서 TrustedTimeClient 활용하기

// 애플리케이션 클래스에서 TrustedTimeClient 가져오기
val myApp = applicationContext as TrustedTimeDemoApplication

// 클라이언트가 null일 경우 시스템 시간을 대신 사용
val currentTimeMillis =
    myApp.trustedTimeClient?.computeCurrentUnixEpochMillis()
        ?: System.currentTimeMillis()
// Instant 객체가 필요하면 trustedTimeClient.computeCurrentInstant()를 활용하세요.

4. Activity 등 단기 컴포넌트에서 사용하기

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
  @Inject
  lateinit var trustedTimeAccessor: TrustedTimeAccessor

  private var trustedTimeClient: TrustedTimeClient? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 생략된 코드...
    trustedTimeAccessor.createClient().addOnCompleteListener { task ->
      if (task.isSuccessful) {
          // 클라이언트 저장
          trustedTimeClient = task.result
      } else {
         // 오류 처리 (재시도하거나 다른 시간원 사용)
          val exception = task.exception
      }
    }
  }

  private fun getCurrentTimeInMillis() : Long? {
    return trustedTimeClient?.computeCurrentUnixEpochMillis()
  }
}

TrustedTime API 사용 조건 및 주의사항

TrustedTime API는 Android 5 (Lollipop) 이상, Google Play 서비스를 실행하는 모든 기기에서 사용할 수 있습니다. API 사용을 위해서는 `com.google.android.gms:play-services-time:16.0.1` 이상의 의존성을 추가해야 하며, 별도의 권한은 필요하지 않습니다. 단, 기기가 부팅 후 인터넷에 연결되어 있어야 올바른 타임스탬프를 받을 수 있습니다. 만약 부팅 후 한 번도 인터넷에 접속하지 않았다면 타임스탬프가 제공되지 않을 수 있으니 주의하세요.

또한, 기기 내부 시계는 온도, 절전 모드, 배터리 상태 등 다양한 요인으로 인해 약간의 오차가 발생할 수 있습니다. TrustedTime API는 이러한 오차 범위를 함께 제공하지만, 완벽하게 시간 조작을 막아주지는 않는다는 점을 유념해야 합니다.

마무리

TrustedTime API는 앱의 시간 관련 문제를 해결하고 데이터 일관성과 보안을 크게 향상시킬 수 있는 강력한 도구입니다. 안정적이고 신뢰할 수 있는 시간 관리가 필요한 앱이라면 꼭 한번 적용해 보시기 바랍니다.


링크

원문

 

TrustedTime API: Introducing a reliable approach to time keeping for your apps

The Trusted Time API in Google Play Services offers developers a reliable, accurate time source independent of device settings to ensure consistency.

android-developers.googleblog.com

참고자료

 

Time API  |  Google for Developers

The Time API provides access to time signals backed by Google's accurate time-keeping service.

developers.google.com

 

TrustedTime  |  Google Play services  |  Google for Developers

com.google.android.gms.dtdi

developers.google.com