一律開啟應用程式和系統微光模式

本指南說明如何讓應用程式一律處於開啟狀態、如何回應電源狀態轉換,以及如何管理應用程式行為,以便在節省電池用量的同時提供良好的使用者體驗。

持續顯示應用程式會對電池續航力造成重大影響,因此在新增這項功能時,請考量電力影響。

核心概念

當 Wear OS 應用程式以全螢幕模式顯示時,會處於下列兩種電源狀態之一:

  • 互動式:螢幕處於全亮度狀態的高耗電狀態,可讓使用者進行完整互動。
  • Ambient:低耗電狀態,螢幕會調暗以節省電力。在這個狀態下,應用程式的 UI 仍會佔滿整個畫面,但系統可能會透過模糊處理或重疊時間等內容來變更其外觀。這也稱為「微光模式」

作業系統會控制這些狀態之間的轉換。

「一律啟用的應用程式」是指在互動微光狀態下皆會顯示內容的應用程式。

當裝置處於低耗電量 微光狀態時,如果螢幕長亮應用程式持續顯示其 UI,則會被視為處於ambiactive 模式

系統轉場和預設行為

當應用程式處於前景時,系統會根據使用者閒置期間觸發的兩個逾時時間,管理電源狀態轉換。

  • 逾時期限 #1:從互動狀態切換至微光狀態:在使用者閒置一段時間後,裝置會進入微光狀態。
  • 逾時 #2:返回錶面:在一段時間內沒有任何操作後,系統可能會隱藏目前的應用程式,並顯示錶面。

系統完成第一次轉換並進入「Ambient」狀態後,預設行為取決於 Wear OS 版本和應用程式的設定:

  • 在 Wear OS 5 以下版本,系統會顯示已暫停應用程式的模糊螢幕截圖,並在頂端疊加時間。
  • Wear OS 6 以上版本中,如果應用程式指定 SDK 36 以上版本,則會視為一律打開。螢幕會調暗,但應用程式會繼續執行,且仍會顯示在螢幕上。(更新頻率可能低至每分鐘一次)。

自訂微光狀態的行為

無論預設系統行為為何,您都可以在所有 Wear OS 版本中,使用 AmbientLifecycleObserver 來監聽狀態轉換的回呼,在 Ambient 狀態下自訂應用程式的外觀或行為。

使用 AmbientLifecycleObserver

如要回應微光模式事件,請使用 AmbientLifecycleObserver 類別:

  1. 實作 AmbientLifecycleObserver.AmbientLifecycleCallback 介面。請使用 onEnterAmbient() 方法調整 UI,以便在低耗電量狀態下運作,並使用 onExitAmbient() 還原為完整互動式顯示畫面。

    val ambientCallback = object : AmbientLifecycleObserver.AmbientLifecycleCallback {
        override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) {
            // ... Called when moving from interactive mode into ambient mode.
            // Adjust UI for low-power state: dim colors, hide non-essential elements.
        }
    
        override fun onExitAmbient() {
            // ... Called when leaving ambient mode, back into interactive mode.
            // Restore full UI.
        }
    
        override fun onUpdateAmbient() {
            // ... Called by the system periodically (typically once per minute)
            // to allow the app to update its display while in ambient mode.
        }
    }
    
  2. 建立 AmbientLifecycleObserver,並將其註冊至活動或可組合項的生命週期。

    private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback)
    
    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(ambientObserver)
    
        // ...
    }
    
  3. 呼叫 removeObserver() 即可移除 onDestroy() 中的觀察器。

對於使用 Jetpack Compose 的開發人員,Horologist 程式庫提供了實用的公用程式,也就是 AmbientAware 可組合函式,可簡化此模式的實作方式。

環境感應 TimeText

在 Wear OS 6 中,TimeText 小工具會根據環境光線調整亮度,因此不需要自訂觀察器。當裝置處於「Ambient」狀態時,這項功能會自動每分鐘更新一次,無須額外加入任何程式碼。

控制螢幕開啟時間

以下各節說明如何管理應用程式在螢幕上顯示的時間長度。

避免返回含有持續性活動的錶面

在「Ambient」狀態一段時間後 (逾時 #2),系統通常會返回錶面。使用者可以在系統設定中設定逾時時間長度。在某些情況下 (例如使用者追蹤健身活動),應用程式可能需要保持較長的顯示時間。

在 Wear OS 5 以上版本中,您可以實作持續性活動來避免這種情況。如果應用程式要顯示使用者正在進行的任務相關資訊 (例如健身工作階段),您可以使用 Ongoing Activity API,讓應用程式在任務結束前持續顯示。如果使用者手動返回錶面,持續性活動指標會提供一鍵返回應用程式的操作方式

如要實作這項功能,持續性通知的觸控意圖必須指向一律開啟活動,如以下程式碼片段所示:

private fun createNotification(): Notification {
    val activityIntent =
        Intent(this, AlwaysOnActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        }

    val pendingIntent =
        PendingIntent.getActivity(
            this,
            0,
            activityIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )

    val notificationBuilder =
        NotificationCompat.Builder(this, CHANNEL_ID)
            // ...
            // ...
            .setOngoing(true)

    // ...

    val ongoingActivity =
        OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
            // ...
            // ...
            .setTouchIntent(pendingIntent)
            .build()

    ongoingActivity.apply(applicationContext)

    return notificationBuilder.build()
}

讓螢幕保持開啟,並防止進入微光狀態

在極少數情況下,您可能需要完全禁止裝置進入微光狀態。也就是說,避免發生超時 #1。如要這麼做,您可以使用 FLAG_KEEP_SCREEN_ON 視窗標記。這個功能可做為喚醒鎖定,讓裝置維持在「交互」狀態。這項功能會嚴重影響電池續航力,因此請務必謹慎使用。

微光模式建議

如要提供最佳使用者體驗,並在Ambient 模式下節省電力,請遵循下列設計指南。

  • 使用簡約、低耗電量的螢幕
    • 至少保留 85% 的螢幕黑色。
    • 為大型圖示或按鈕使用外框,而非實心填充。
    • 只顯示最重要的資訊,將次要詳細資料移至互動式螢幕。
    • 避免使用大片純色區塊和不具功能性的品牌或背景圖片。
  • 確保內容適時更新
    • 對於經常變更的資料 (例如秒錶、運動距離或時間),請顯示 -- 等預留位置內容,避免使用者誤以為內容是最新的。
    • 移除持續更新的進度指標,例如倒數環和媒體工作階段。
    • onUpdateAmbient() 回呼應僅用於必要更新,通常每分鐘一次。
  • 維持一致的版面配置
    • 互動微光模式中,讓元素保持在相同位置,以便順利轉換。
    • 一律顯示時間。
  • 具備情境感知功能
    • 如果裝置進入微光模式時,使用者正在設定或設定畫面,建議您顯示應用程式中更相關的畫面,而非設定檢視畫面。
  • 處理裝置專屬需求
    • 在傳遞至 onEnterAmbient()AmbientDetails 物件中:
      • 如果 deviceHasLowBitAmbienttrue,請盡可能停用反鋸齒功能。
      • 如果 burnInProtectionRequiredtrue,請定期稍微移動 UI 元素,並避免顯示實心白色區域,以免螢幕出現燒入現象。

偵錯和測試

在開發或測試裝置處於環境模式時,應用程式行為可能會使用以下 adb 指令:

# put device in ambient mode if the always on display is enabled in settings
# (and not disabled by other settings, such as theatre mode)
$ adb shell input keyevent KEYCODE_SLEEP

# put device in interactive mode
$ adb shell input keyevent KEYCODE_WAKEUP

示例:健身應用程式

舉例來說,健身應用程式需要在整個運動時段向使用者顯示指標。應用程式必須在背景狀態轉換期間保持可見,並避免遭到錶面取代。

為達成此目標,開發人員應採取下列做法:

  1. 實作 AmbientLifecycleObserver 來處理互動式環境狀態之間的 UI 變更,例如調低螢幕亮度和移除非必要資料。
  2. 微光螢幕狀態建立新的低耗電版版面配置,並遵循最佳做法。
  3. 在健身期間使用 Ongoing Activity API,可防止系統返回錶面。

如需完整實作方式,請參閱 GitHub 上的 Exercise 範例,該範例是以 Compose 為基礎。這個範例也示範如何使用 Horologist 程式庫中的 AmbientAware 可組合項,簡化 Compose 中的環境模式處理作業。