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

本指南說明如何讓應用程式保持運作、如何因應電源狀態轉換,以及如何管理應用程式行為,在節省電量的同時提供良好的使用者體驗。

持續顯示應用程式會大幅影響電池續航力,因此新增這項功能時,請注意對電量的影響。

核心概念

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

  • 互動:高耗電狀態,螢幕會以全螢幕亮度顯示, 讓使用者充分互動。
  • 微光:低耗電狀態,螢幕會調暗以節省電力。在此狀態下,應用程式的 UI 仍會佔滿整個螢幕,但系統可能會模糊處理或疊加時間等內容,藉此改變外觀。這也稱為「微光模式」

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

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

如果應用程式在裝置處於低功耗的微光狀態時,持續顯示自己的 UI,則稱為處於微光啟用模式

系統轉場效果和預設行為

應用程式在前台執行時,系統會根據使用者閒置觸發的兩個逾時,管理電源狀態轉換。

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

系統第一次轉換為微光狀態後,預設行為會因 Wear OS 版本和應用程式設定而異:

  • 在 Wear OS 5 以下版本,系統會顯示暫停應用程式的模糊螢幕截圖,並在上方疊加時間。這個狀態在下列流程圖中以「AOD Lite」節點表示。
  • 在 Wear OS 6 以上版本,如果應用程式指定 SDK 36 以上版本,系統會視為「一律開啟」。螢幕會調暗,但應用程式會繼續執行並保持顯示狀態。(更新頻率可能低至每分鐘一次)。下列流程圖中的「Global AOD」節點代表這個狀態。

自訂微光狀態的行為

無論系統預設行為為何,在所有 Wear OS 版本上,您都可以使用 AmbientLifecycleObserver 監聽狀態轉換的回呼,在微光狀態下自訂應用程式的外觀或行為。這個狀態在下列流程圖中,以「Ambiactive Mode」節點表示。

使用 AmbientLifecycleObserver

如要對微光模式事件做出反應,請使用 AmbientLifecycleObserver 類別:

  1. 實作 AmbientLifecycleObserver.AmbientLifecycleCallback 介面。使用 onEnterAmbient() 方法調整使用者介面,使其符合低功耗狀態,並使用 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() 中的觀察器。

    override fun onDestroy() {
        super.onDestroy()
        lifecycle.removeObserver(ambientObserver)
    
        // ...
    }

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

可感知環境的 TimeText

在 Wear OS 6 中,TimeText 小工具可感知微光模式,因此不需要自訂觀察器。裝置處於微光狀態時,系統會每分鐘自動更新一次,無須額外程式碼。

環境動作流程圖

下方的流程圖說明系統如何根據裝置的 Wear OS 版本、應用程式的 targetSdkVersion,以及是否實作 AmbientLifecycleCallback,判斷微光模式行為。

這張流程圖說明 Wear OS 微光模式的決策邏輯。本文說明裝置的 OS 版本和應用程式設定如何決定三種結果之一:模糊疊加層、全域 AOD 或應用程式管理的 Ambiactive 模式。
圖 1.:這張流程圖說明 Wear OS 微光模式的決策邏輯。

控制螢幕開啟時間

以下各節說明如何管理應用程式在螢幕上停留的時間。

避免透過持續進行的活動或即時更新返回錶面

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

在 Wear OS 5 以上版本中,您可以導入持續性活動,防止系統顯示這類通知。如果應用程式顯示使用者正在進行的工作相關資訊 (例如健身活動),您可以使用 Ongoing Activity API,讓應用程式保持顯示狀態,直到工作結束為止。如果使用者手動返回錶面,持續性活動指標提供一鍵式方式,讓他們返回您的應用程式。

或者,在 Wear OS 7 以上版本中,您可以使用即時更新取代持續性活動。為維持回溯相容性,請繼續在搭載 Wear OS 6 以下版本的裝置上支援「進行中的活動」。

如要實作這項功能,持續性通知的觸控意圖必須指向常時運作活動,如下列程式碼片段所示:

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)

val notification = notificationBuilder.build()

讓螢幕保持開啟,避免進入微光模式

在極少數情況下,您可能需要完全禁止裝置進入微光狀態。也就是避免發生逾時 #1。如要這麼做,請使用 FLAG_KEEP_SCREEN_ON 視窗旗標。這項功能會做為 Wake Lock,讓裝置保持在「互動」Interactive狀態。請務必謹慎使用這項功能,因為這會大幅影響電池續航力。

微光模式建議

為提供最佳使用者體驗,並在微光模式下節省電力,請遵循這些設計指南。這些建議會優先考量清楚的使用者體驗,避免誤導資訊並減少視覺混亂,同時盡量提升顯示效果。

  • 減少視覺干擾,降低螢幕耗電量。簡潔的極簡風 UI 可向使用者表明應用程式處於低耗電狀態,並限制亮像素,大幅節省電量。
    • 至少將 85% 的畫面保留為黑色。
    • 只顯示最重要的資訊,並將次要詳細資料移至互動式螢幕。
    • 大型圖示或按鈕應使用外框,而非實心填滿。
    • 避免使用大面積的純色區塊,以及無實際用途的品牌宣傳或背景圖片。
  • 處理過時的動態資料
    • 為節省電力,系統只會定期 (通常每分鐘一次) 叫用 onUpdateAmbient() 回呼。因此,任何經常變更的資料 (例如碼錶、心率或運動距離) 在更新之間都會過時。為避免顯示誤導和不正確的資訊,請監聽 onEnterAmbient 回呼,並將這些即時值替換為靜態預留位置內容,例如 --
  • 維持一致的版面配置
    • 在「互動」和「微光」模式中,讓元素保持在相同位置,打造流暢的轉換效果。
    • 一律顯示時間。
  • 瞭解情境
    • 如果裝置進入微光模式時,使用者正在設定或配置畫面,請考慮顯示應用程式中更相關的畫面,而非設定檢視畫面。
  • 處理裝置專屬需求
    • 在傳遞至 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. 請按照最佳做法,為 Ambient 狀態建立新的低耗電版面配置
  3. 在運動期間使用 Ongoing Activity API (或 Wear OS 7 以上版本的即時更新),防止系統返回錶面。

如需完整實作方式,請參閱 GitHub 上以 Compose 為基礎的運動範例。本範例也示範如何使用 Horologist 程式庫的 AmbientAware 可組合函式,簡化 Compose 中的微光模式處理程序。