시계 화면 푸시를 위해 Wear OS 앱 구성

시계 화면 푸시를 사용하면 앱이 Wear OS 기기에서 시계 화면을 관리할 수 있습니다. 여기에는 시계 화면 추가, 업데이트, 삭제는 물론 활성 시계 화면 설정도 포함됩니다. 워치 페이스 푸시 API를 사용하도록 Wear OS 앱을 구성합니다.

설정

필요한 종속 항목을 포함합니다.

implementation("androidx.wear.watchfacepush:watchfacepush:1.0.0-alpha01")

AndroidManifest.xml에 다음을 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Required to use the Watch Face Push API.  -->
    <uses-permission android:name="com.google.wear.permission.PUSH_WATCH_FACES" />

    <!-- Required to be able to call the setWatchFaceAsActive() method. -->
    <uses-permission android:name="com.google.wear.permission.SET_PUSHED_WATCH_FACE_AS_ACTIVE" />

</manifest>

관리자 인스턴스에 대한 참조 가져오기

WatchFacePushManager의 인스턴스를 가져옵니다.

val manager = WatchFacePushManagerFactory.createWatchFacePushManager(context)

WatchFacePushManager는 워치 페이스 푸시와 상호작용하는 모든 메서드에 대한 액세스를 제공합니다.

슬롯 작업

시계 화면 푸시를 사용할 때 중요한 개념은 슬롯입니다. 슬롯은 애플리케이션에 속한 설치된 시계 화면을 처리하는 방법입니다. 시스템은 마켓에서 사용할 수 있는 최대 슬롯 수를 설정합니다. Wear OS 6에서는 한도가 1입니다.

시계 화면을 업데이트하거나 삭제할 때 slotId는 작업을 실행할 시계 화면을 식별하는 데 사용됩니다.

시계 화면 나열

설치된 시계 화면 세트를 나열하려면 listWatchFaces()을 사용하세요.

val response = watchFacePushManager.listWatchFaces()
val installedList = response.installedWatchFaceDetails
val remainingSlots = response.remainingSlots

이를 통해 슬롯을 사용할 수 있는지 또는 다른 시계 화면을 추가하려면 기존 시계 화면을 교체해야 하는지 확인할 수 있습니다. 목록에는 설치된 시계 화면에 관한 세부정보도 표시됩니다. 예를 들어 특정 시계 화면 패키지가 설치되어 있는지 확인하려면 다음을 실행합니다.

suspend fun isInstalled(packageName: String) = watchFacePush.listWatchFaces()
    .installedWatchFaceDetails.any { it.packageName == packageName }

시계 화면 추가

listWatchFaces 응답에 따라 사용 가능한 슬롯이 있는 경우 addWatchFace() 메서드를 사용해야 합니다.

try {
    // Supply the validation token along with the watch face package data itself.
    val slot = watchFacePushManager.addWatchFace(parcelFileDescriptor, token)
    Log.i(TAG, "${slot.packageName} (${slot.versionCode}) added in slot ${slot.slotId}")
} catch (e: AddWatchFaceException) {
    // Something went wrong adding the watch face.
}

시계 화면 업데이트

시계 화면을 업데이트하면 지정된 슬롯의 콘텐츠를 새 패키지로 바꿀 수 있습니다. 동일한 시계 화면을 최신 버전으로 업그레이드하거나 시계 화면을 완전히 다른 시계 화면으로 대체하는 것일 수 있습니다.

// Replacing the com.example.watchfacepush.green watch face with
// com.example.watchfacepush.red.
val slotId = watchFacePushManager.listWatchFaces().installedWatchFaceDetails.
    firstOrNull { it.packageName == "com.example.watchfacepush.green" }?.slotId

try {
    watchFacePushManager.updateWatchFace(slotId, redParcelFileDesc, redValidationToken)
} catch (e: UpdateWatchFaceException) {
    // Something went wrong updating the watch face.
}

시계 화면 삭제하기

시계 화면을 삭제하려면 다음 단계를 따르세요.

// Remove the com.example.watchfacepush.green watch face.
val slotId = watchFacePushManager.listWatchFaces().installedWatchFaceDetails.
    firstOrNull { it.packageName == "com.example.watchfacepush.green" }?.slotId

try {
    watchFacePushManager.removeWatchFace(slotId)
} catch (e: RemoveWatchFaceException) {
    // Something went wrong removing the watch face.
}

이렇게 하면 시계 화면을 시스템 시계 화면 선택기에서 항상 찾을 수 있고, 로고를 눈에 띄게 표시할 수 있으며, 휴대폰에서 Marketplace 앱을 실행하는 버튼을 표시할 수도 있습니다.

워치 배경화면이 활성 상태인지 확인하기

마켓에 활성 시계 모드가 설정되어 있는지 확인하는 것은 사용자가 원활한 환경을 경험하도록 하는 데 중요합니다. 마켓에 이미 활성 시계 모드가 설정되어 있는 경우 사용자가 다른 시계 모드를 선택하려면 마켓 앱을 통해 현재 시계 모드를 교체하기만 하면 됩니다. 하지만 마켓에 활성 시계 화면이 설정되어 있지 않으면 휴대전화 앱에서 사용자에게 더 많은 안내를 제공해야 합니다. 이 사용자 환경을 처리하는 방법에 관한 자세한 내용은 전화 앱 섹션을 참고하세요.

마켓에 활성 시계 화면이 설정되어 있는지 확인하려면 다음 로직을 사용하세요.

val hasActiveWatchFace = watchFacePushManager.listWatchFaces()
    .installedWatchFaceDetails
    .any {
        watchFacePushManager.isWatchFaceActive(it.packageName)
    }

기본 시계 화면 제공

시계 화면 푸시를 사용하면 마켓 앱이 설치될 때 기본 시계 화면을 설치할 수 있습니다. 이 자체는 해당 기본 시계 화면을 활성으로 설정하지는 않지만 (활성 시계 화면 설정 참고) 시계 화면이 시스템 시계 화면 선택기에서 사용 가능하도록 합니다.

이 기능을 사용하려면 다음을 실행합니다.

  1. Wear OS 앱 빌드에서 다음 경로에 기본 시계 화면을 포함합니다. assets/default_watchface.apk
  2. AndroidManifest.xml에 다음 항목을 추가합니다.

    <application ...>
    <meta-data
        android:name="com.google.android.wearable.marketplace.DEFAULT_WATCHFACE_VALIDATION_TOKEN"
        android:value="@string/default_wf_token" />
    

활성 워치 배경화면 설정

워치 배경화면 푸시는 마켓 앱이 활성 워치 배경화면을 설정하는 수단을 제공합니다.

즉, 현재 활성 워치 배경화면이 마켓에 속하지 않는 경우 앱이 활성 워치 배경화면을 마켓에 속하는 워치 배경화면으로 설정할 수 있습니다. 마켓에 이미 활성 워치 배경화면이 있는 경우 이를 다른 워치 배경화면으로 변경하려면 updateWatchFace를 호출하여 워치 배경화면 슬롯의 콘텐츠를 다른 워치 배경화면으로 대체해야 합니다.

활성 워치 배경화면 설정은 2단계 프로세스입니다.

  1. 활성 시계 화면을 설정하는 데 필요한 Android 권한을 획득합니다.
  2. setWatchFaceAsActive 메서드를 호출합니다.

활성 워치 배경화면을 설정하는 권한 획득

필요한 권한은 SET_PUSHED_WATCH_FACE_AS_ACTIVE이며, 매니페스트에 추가해야 합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    <uses-permission android:name="com.google.wear.permission.SET_PUSHED_WATCH_FACE_AS_ACTIVE" />
</manifest>

이는 런타임 권한이므로 앱이 실행될 때 사용자에게 이 권한을 요청해야 합니다 (이 작업을 지원하는 Accompanist 라이브러리 참고).

워치 배경화면을 활성으로 설정

권한이 부여되면 활성화되어야 하는 시계 모드의 슬롯 ID에서 setWatchFaceAsActive를 호출합니다.

watchFacePushManager.setWatchFaceAsActive(slotId)

이 수단을 사용한 후에는 휴대전화 앱에서 활성 시계 모드를 수동으로 설정하는 방법을 안내해야 합니다.

시계 화면 APK에서 추가 메타데이터 읽기

WatchFaceSlot 객체는 시계 화면에서 선언할 수 있는 추가 정보를 가져오는 수단도 제공합니다.

이는 동일한 시계 화면의 사소한 변형이 있는 시나리오에서 특히 유용합니다. 예를 들어 다음과 같이 정의된 시계 화면이 있을 수 있습니다.

  • Package name: com.myapp.watchfacepush.mywatchface
  • 패키지 버전: 1.0.0

하지만 이 시계 화면은 4개의 다른 APK로 제공될 수 있습니다. 모두 거의 동일하지만 시계 화면 형식 XML의 ColorConfiguration에 설정된 기본 색상(빨간색, 노란색, 녹색파란색)이 다릅니다.

이러한 약간의 차이는 다음 네 개의 APK에 반영됩니다.

<!-- For watch face com.myapp.watchfacepush.mywatchface -->
<property
        android:name="default_color"
        android:value="red" />

맞춤 속성을 사용하면 앱에서 설치된 변형을 확인할 수 있습니다.

watchFaceDetails
    .getMetaDataValues("com.myapp.watchfacepush.mywatchface.default_color")
    .invoke()

고려사항

앱에서 시계 화면 푸시를 구현할 때 고려해야 할 중요한 사항은 전력 소비에 집중하고, 번들로 제공되는 시계 화면을 캐싱 및 업데이트하고, 대표적인 기본 시계 화면을 제공하는 것입니다.

전원

Wear OS에서 실행되는 모든 앱의 주요 고려사항은 전력 소비입니다. 마켓 앱의 Wear OS 구성요소의 경우:

  1. 앱은 가능한 한 적게, 드물게 실행해야 합니다 (사용자가 직접 상호작용하는 경우 제외). 여기에는 다음이 포함됩니다.
    • 전화 앱에서 앱이 절전 모드에서 해제되는 것을 최소화
    • WorkManager 작업 실행 최소화
  2. 시계가 충전 중일 때 분석 보고를 예약합니다.
    1. Wear OS 앱 또는 기타 측정항목의 사용 통계를 보고하려면 requiresCharging 제약 조건과 함께 WorkManager를 사용하세요.
  3. 시계가 충전 중이고 Wi-Fi를 사용할 때 업데이트 예약:
    1. 설치된 워치 배경화면의 버전을 확인하고 자동으로 업데이트하는 것이 좋습니다. requiresNetworkType의 경우 requiresCharging 제약 조건과 UNMETERED 네트워크 유형을 다시 사용합니다.
    2. 충전 중일 때는 기기가 Wi-Fi에 액세스할 수 있을 가능성이 높습니다. 업데이트된 APK를 빠르게 다운로드하기 위해 Wi-Fi를 요청하고 완료되면 네트워크를 해제합니다.
    3. 마켓에서 오늘의 시계 화면을 제공하는 경우에도 동일한 안내가 적용됩니다. 시계가 충전되는 동안 이를 미리 다운로드하세요.
  4. 활성 시계 화면을 확인하는 작업을 예약하지 마세요.
    1. 마켓에 활성 시계 화면이 있는지, 어떤 시계 화면인지 주기적으로 확인하면 배터리가 소모됩니다. 이 방법은 피하세요.
  5. 시계에서 알림을 사용하지 않음:
    1. 앱에서 알림을 사용하는 경우 사용자가 휴대전화 앱을 열어 여정을 계속할 수 있도록 휴대전화에 집중하세요. setLocalOnly를 사용하여 시계 앱으로 브리징되지 않도록 합니다.

캐싱

표준 마켓 예시에서는 시계 화면이 휴대전화에서 시계로 전송됩니다. 이 연결은 일반적으로 블루투스 연결이며 속도가 매우 느릴 수 있습니다.

더 나은 사용자 환경을 제공하고 재전송 전력을 절약하려면 Wear OS 기기에 소규모 캐시를 구현하여 몇 개의 APK를 저장하는 것이 좋습니다.

사용자가 다른 시계 화면을 사용해 보다가 이전에 선택한 시계 화면으로 되돌리기로 결정한 경우 이 작업은 거의 즉시 이루어집니다.

마찬가지로 Wear OS 기기가 충전되는 동안 시계 화면이 다운로드되는 오늘의 시계 화면 또는 유사한 스킴의 사전 캐싱에 사용할 수 있습니다.

번들로 제공되는 시계 화면 업데이트

앱에는 앞에서 설명한 대로 기본 시계 화면 애셋이 포함될 수 있습니다. 이 시계 페이스는 마켓 앱이 설치될 때 시스템에 설치되지만 마켓 앱 업데이트에 최신 버전이 번들로 제공되더라도 시계 페이스는 업데이트되지 않습니다.

이 상황을 처리하려면 마켓 앱이 MY_PACKAGE_REPLACED 브로드캐스트 작업을 수신 대기하고 패키지 애셋에서 번들로 제공된 시계 화면을 업데이트해야 하는지 확인해야 합니다.

대표 기본 시계 화면

기본 시계 화면은 사용자가 마켓을 찾고 사용할 수 있도록 지원하는 좋은 방법입니다. 마켓이 설치되면 시계 화면도 설치되므로 사용자가 시계 화면 갤러리에서 시계 화면을 찾을 수 있습니다.

기본 시계 화면으로 작업할 때 고려해야 할 사항은 다음과 같습니다.

  • 사용자가 마켓 앱에서 시계 화면을 제거하도록 선택한 경우 removeWatchFace를 사용하지 마세요. 대신 이 경우 updateWatchFace를 사용하여 시계 화면을 기본 시계 화면으로 되돌리세요. 이렇게 하면 사용자가 갤러리에서 시계 화면을 찾아 설정할 수 있습니다.
  • 로고와 테마를 통해 기본 시계 화면을 간단하고 즉시 알아볼 수 있도록 만드세요. 이렇게 하면 사용자가 시계 화면 갤러리에서 시계 화면을 찾을 수 있습니다.
  • 기본 시계 화면에 전화 앱을 여는 버튼을 추가합니다. 이는 다음 두 단계로 달성할 수 있습니다.

    1. Wear OS 앱을 사용하여 인텐트를 실행하도록 시계 화면에 Launch 요소를 추가합니다(예: 다음).

      <Launch target="com.myapp/com.myapp.LaunchOnPhoneActivity" />

    2. LaunchOnPhoneActivity에서 RemoteActivityHelper을 사용하여 전화 앱을 실행합니다.