當使用者不再使用手錶時,Wear OS 會自動將應用程式改為低功率模式。這就是所謂的「系統微光模式」。如果使用者在特定時間範圍內再次與手錶互動,Wear OS 會將使用者帶回先前離開的應用程式。
對於特定用途,例如,如果使用者想在跑步期間查看心率和配速,也可以控制低耗電模式 (微光模式) 所顯示的內容。在微光模式和互動模式中執行的 Wear OS 應用程式,稱為「一律啟用的應用程式」。
持續顯示應用程式會影響到電池續航力,因此在應用程式新增這項功能時,請注意這項影響。
設定專案
如要支援微光模式,請按照下列步驟操作:
- 根據「建立及執行穿戴式應用程式」頁面上的設定來建立或更新專案。
- 將
WAKE_LOCK
權限新增至 Android 資訊清單檔案:
<uses-permission android:name="android.permission.WAKE_LOCK" />
使用 AmbientModeSupport 類別的微光模式
如需使用 AmbientModeSupport
類別,請執行以下操作:
-
建立
FragmentActivity
的子類別或其中一個子類別。 -
導入
AmbientCallbackProvider
介面,如以下範例所示。覆寫getAmbientCallback()
方法,以提供回應 Android 系統微光事件所需的回呼 (在後續步驟中,您將建立自訂回呼類別。)Kotlin
class MainActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider { ... override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback = MyAmbientCallback() ... }
Java
public class MainActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider { ... @Override public AmbientModeSupport.AmbientCallback getAmbientCallback() { return new MyAmbientCallback(); } ... }
-
在
onCreate()
方法中,呼叫AmbientModeSupport.attach(FragmentActivity)
來啟用微光模式。這個方法會回傳AmbientModeSupport.AmbientController
。這個控制器可讓您檢查回呼以外的微光狀態。建議您保留對AmbientModeSupport.AmbientController
物件的參照:Kotlin
class MainActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider { ... /* * Declare an ambient mode controller, which will be used by * the activity to determine if the current mode is ambient. */ private lateinit var ambientController: AmbientModeSupport.AmbientController ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... ambientController = AmbientModeSupport.attach(this) } ... }
Java
public class MainActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider { ... /* * Declare an ambient mode controller, which will be used by * the activity to determine if the current mode is ambient. */ private AmbientModeSupport.AmbientController ambientController; ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... ambientController = AmbientModeSupport.attach(this); } ... }
-
建立內部類別,可擴充
AmbientCallback
類別以處理微光事件。這個類別會成為您在步驟 2 建立的方法傳回的物件,如以下範例所示:Kotlin
private class MyAmbientCallback : AmbientModeSupport.AmbientCallback() { override fun onEnterAmbient(ambientDetails: Bundle?) { // Handle entering ambient mode } override fun onExitAmbient() { // Handle exiting ambient mode } override fun onUpdateAmbient() { // Update the content } }
Java
private class MyAmbientCallback extends AmbientModeSupport.AmbientCallback { @Override public void onEnterAmbient(Bundle ambientDetails) { // Handle entering ambient mode } @Override public void onExitAmbient() { // Handle exiting ambient mode } @Override public void onUpdateAmbient() { // Update the content } }
如需詳細資訊和最佳做法,請參閱 GitHub 上的「AlwaysOnKotlin 範例」。
使用 WearableActivity 類別的微光模式
對於新專案和現有專案,您可以透過更新專案設定,新增支援 Wear 應用程式的微光模式。
建立支援微光模式的活動
您可以在活動中使用
WearableActivity
類別啟用微光模式,如下所示:
- 建立可擴充
WearableActivity
的活動。 -
在活動中的
onCreate()
方法中呼叫setAmbientEnabled()
方法。
下列程式碼片段說明如何在活動中啟用微光模式:
Kotlin
class MainActivity : WearableActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setAmbientEnabled() ... } }
Java
public class MainActivity extends WearableActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setAmbientEnabled(); ... }
處理模式之間的轉換
如果使用者在應用程式顯示期間已有一段時間未與應用程式互動,或是螢幕被覆蓋,系統會把活動切換為微光模式。
應用程式切換至微光模式後,請將活動使用者介面更新為更基本的版面配置以降低耗電量。使用含有少量白色圖像和文字的黑色背景。
如要簡化從互動模式到微光模式的轉換作業,建議您在螢幕上保留類似的項目位置。
注意:在微光模式下,請停用螢幕上的任何互動元素,例如按鈕。
當活動切換至微光模式時,系統會呼叫微光回呼的
onEnterAmbient()
方法。下列程式碼片段說明如何在系統變更為微光模式後將文字顏色變更為白色,並停用反鋸齒功能:
Kotlin
override fun onEnterAmbient(ambientDetails: Bundle?) { super.onEnterAmbient(ambientDetails) stateTextView.setTextColor(Color.WHITE) stateTextView.paint.isAntiAlias = false }
Java
@Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); stateTextView.setTextColor(Color.WHITE); stateTextView.getPaint().setAntiAlias(false); }
當使用者輕觸螢幕或抬起手腕時,活動就會從微光模式切換回互動模式。系統會呼叫 onExitAmbient()
方法。覆寫這個方法即可更新使用者介面的版面配置,讓應用程式以全彩的互動式狀態顯示。
以下程式碼片段顯示如何將文字顏色變更為綠色,以及如何在系統切換至互動模式時啟用反鋸齒:
Kotlin
override fun onExitAmbient() { super.onExitAmbient() stateTextView.setTextColor(Color.GREEN) stateTextView.paint.isAntiAlias = true }
Java
@Override public void onExitAmbient() { super.onExitAmbient(); stateTextView.setTextColor(Color.GREEN); stateTextView.getPaint().setAntiAlias(true); }
在微光模式下更新內容
微光模式可讓您以使用者的新資訊更新畫面,但必須在顯示更新資訊和電池用量之間取得平衡。在微光模式中,建議每分鐘更新螢幕一次或少於一次。
如要更新應用程式內容,請覆寫微光回呼中的
onUpdateAmbient()
方法:
Kotlin
override fun onUpdateAmbient() { super.onUpdateAmbient() // Update the content }
Java
@Override public void onUpdateAmbient() { super.onUpdateAmbient(); // Update the content }
我們不建議在微光模式下每分鐘更新 Wear OS 應用程式超過一次。如果是需要頻繁更新的應用程式,請使用 AlarmManager
物件以喚醒處理器,並增加螢幕更新的頻率。
如要執行在微光模式下更頻繁地更新內容的鬧鐘,請按照下列步驟操作:
- 準備鬧鐘管理員。
- 設定更新的頻率。
- 檢查裝置目前是否處於微光模式,並在活動切換至微光模式時,安排下次更新作業。
- 在活動切換至互動模式或活動停止時取消鬧鐘。
注意:鬧鐘管理員可在觸發時建立新的活動執行個體。為避免這種行為,請使用資訊清單中的 android:launchMode="singleInstance"
參數來宣告活動。
以下各節將詳細說明這些步驟。
準備鬧鐘管理員
鬧鐘管理員會啟動 PendingIntent
來更新螢幕並安排下一個鬧鐘。以下範例說明如何在活動的 onCreate()
方法中宣告鬧鐘管理員和待處理意圖:
Kotlin
// Action for updating the display in ambient mode, per our custom refresh cycle private const val AMBIENT_UPDATE_ACTION = "com.your.package.action.AMBIENT_UPDATE" ... private lateinit var ambientUpdateAlarmManager: AlarmManager private lateinit var ambientUpdatePendingIntent: PendingIntent private lateinit var ambientUpdateBroadcastReceiver: BroadcastReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setAmbientEnabled() ambientUpdateAlarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager ambientUpdatePendingIntent = Intent(AMBIENT_UPDATE_ACTION).let { ambientUpdateIntent -> PendingIntent.getBroadcast(this, 0, ambientUpdateIntent, PendingIntent.FLAG_UPDATE_CURRENT) } ambientUpdateBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { refreshDisplayAndSetNextUpdate() } } ... }
Java
// Action for updating the display in ambient mode, per our custom refresh cycle private static final String AMBIENT_UPDATE_ACTION = "com.your.package.action.AMBIENT_UPDATE"; private AlarmManager ambientUpdateAlarmManager; private PendingIntent ambientUpdatePendingIntent; private BroadcastReceiver ambientUpdateBroadcastReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setAmbientEnabled(); ambientUpdateAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent ambientUpdateIntent = new Intent(AMBIENT_UPDATE_ACTION); ambientUpdatePendingIntent = PendingIntent.getBroadcast( this, 0, ambientUpdateIntent, PendingIntent.FLAG_UPDATE_CURRENT); ambientUpdateBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { refreshDisplayAndSetNextUpdate(); } }; ... }
使用 onResume()
和 onPause()
,來註冊及取消註冊廣播接收器:
Kotlin
override fun onResume() { super.onResume() IntentFilter(AMBIENT_UPDATE_ACTION).also { filter -> registerReceiver(ambientUpdateBroadcastReceiver, filter) } } override fun onPause() { super.onPause() unregisterReceiver(ambientUpdateBroadcastReceiver) ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent) }
Java
@Override public void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(AMBIENT_UPDATE_ACTION); registerReceiver(ambientUpdateBroadcastReceiver, filter); ... } @Override public void onPause() { super.onPause(); unregisterReceiver(ambientUpdateBroadcastReceiver); ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent); ... }
更新畫面並安排資料更新時程
在這個範例活動中,鬧鐘管理員在微光模式下每 20 秒觸發一次。當計時器運作時,鬧鐘會觸發意圖以更新畫面,然後設定下一次更新的延遲時間。
以下範例說明如何更新畫面上的資訊,並設定下一次更新的鬧鐘:
Kotlin
// Milliseconds between waking processor/screen for updates private val AMBIENT_INTERVAL_MS: Long = TimeUnit.SECONDS.toMillis(20) ... private fun refreshDisplayAndSetNextUpdate() { if (isAmbient) { // Implement data retrieval and update the screen for ambient mode } else { // Implement data retrieval and update the screen for interactive mode } val timeMs: Long = System.currentTimeMillis() // Schedule a new alarm if (isAmbient) { // Calculate the next trigger time val delayMs: Long = AMBIENT_INTERVAL_MS - timeMs % AMBIENT_INTERVAL_MS val triggerTimeMs: Long = timeMs + delayMs ambientUpdateAlarmManager.setExact( AlarmManager.RTC_WAKEUP, triggerTimeMs, ambientUpdatePendingIntent) } else { // Calculate the next trigger time for interactive mode } }
Java
// Milliseconds between waking processor/screen for updates private static final long AMBIENT_INTERVAL_MS = TimeUnit.SECONDS.toMillis(20); private void refreshDisplayAndSetNextUpdate() { if (isAmbient()) { // Implement data retrieval and update the screen for ambient mode } else { // Implement data retrieval and update the screen for interactive mode } long timeMs = System.currentTimeMillis(); // Schedule a new alarm if (isAmbient()) { // Calculate the next trigger time long delayMs = AMBIENT_INTERVAL_MS - (timeMs % AMBIENT_INTERVAL_MS); long triggerTimeMs = timeMs + delayMs; ambientUpdateAlarmManager.setExact( AlarmManager.RTC_WAKEUP, triggerTimeMs, ambientUpdatePendingIntent); } else { // Calculate the next trigger time for interactive mode } }
設定下一個鬧鐘的時間
覆寫 onEnterAmbient()
方法和 onUpdateAmbient()
方法,設定鬧鐘以更新畫面,如下列範例所示:
Kotlin
override fun onEnterAmbient(ambientDetails: Bundle?) { super.onEnterAmbient(ambientDetails) refreshDisplayAndSetNextUpdate() } override fun onUpdateAmbient() { super.onUpdateAmbient() refreshDisplayAndSetNextUpdate() }
Java
@Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); refreshDisplayAndSetNextUpdate(); } @Override public void onUpdateAmbient() { super.onUpdateAmbient(); refreshDisplayAndSetNextUpdate(); }
注意:在這個範例中,每當畫面需要更新時都會呼叫 refreshDisplayAndSetNextUpdate()
方法。如需更多呼叫這個方法的情境範例,請參閱 GitHub 上的「AlwaysOnKotlin 範例」。
取消鬧鐘
當裝置切換至互動模式時,請在 onExitAmbient()
方法中取消鬧鐘:
Kotlin
override fun onExitAmbient() { super.onExitAmbient() ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent) }
Java
@Override public void onExitAmbient() { super.onExitAmbient(); ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent); }
使用者離開或停止活動時,請在活動的 onDestroy()
方法中取消鬧鐘:
Kotlin
override fun onDestroy() { ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent) super.onDestroy() }
Java
@Override public void onDestroy() { ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent); super.onDestroy(); }