Hướng dẫn này giải thích cách làm cho ứng dụng luôn bật, cách phản ứng với các chuyển đổi trạng thái nguồn và cách quản lý hành vi của ứng dụng để mang lại trải nghiệm tốt cho người dùng trong khi vẫn tiết kiệm pin.
Việc cho phép một ứng dụng liên tục xuất hiện sẽ ảnh hưởng đáng kể đến thời lượng pin, vì vậy bạn hãy cân nhắc ảnh hưởng đến nguồn điện khi thêm tính năng này.
Khái niệm chính
Khi hiển thị ở chế độ toàn màn hình, ứng dụng Wear OS sẽ ở một trong hai trạng thái nguồn:
- Tương tác: Trạng thái tiêu thụ nhiều năng lượng, màn hình ở độ sáng tối đa, cho phép người dùng tương tác đầy đủ.
- Môi trường xung quanh: Trạng thái tiết kiệm pin, trong đó màn hình sẽ giảm độ sáng để tiết kiệm pin. Ở trạng thái này, giao diện người dùng của ứng dụng vẫn chiếm toàn màn hình, nhưng hệ thống có thể thay đổi giao diện bằng cách làm mờ hoặc phủ lên nội dung như thời gian. Chế độ này còn được gọi là Chế độ môi trường xung quanh.
Hệ điều hành kiểm soát quá trình chuyển đổi giữa các trạng thái này.
Ứng dụng luôn bật là một ứng dụng hiển thị nội dung ở cả trạng thái Tương tác và Môi trường xung quanh.
Khi một ứng dụng luôn bật tiếp tục hiển thị giao diện người dùng của riêng ứng dụng đó trong khi thiết bị ở trạng thái Môi trường xung quanh tiết kiệm pin, ứng dụng đó được mô tả là ở chế độ luôn bật.
Hoạt động chuyển đổi hệ thống và hành vi mặc định
Khi một ứng dụng chạy ở nền trước, hệ thống sẽ quản lý các quá trình chuyển đổi trạng thái nguồn điện dựa trên hai thời gian chờ do người dùng không hoạt động kích hoạt.
- Thời gian chờ #1: Trạng thái tương tác sang trạng thái Môi trường xung quanh: Sau một khoảng thời gian người dùng không hoạt động, thiết bị sẽ chuyển sang trạng thái Môi trường xung quanh.
- Thời gian chờ thứ hai: Quay lại mặt đồng hồ: Sau một khoảng thời gian không hoạt động nữa, hệ thống có thể ẩn ứng dụng hiện tại và hiển thị mặt đồng hồ.
Ngay sau khi hệ thống chuyển đổi lần đầu tiên sang trạng thái Môi trường xung quanh, hành vi mặc định sẽ phụ thuộc vào phiên bản Wear OS và cấu hình của ứng dụng:
- Trên Wear OS 5 trở xuống, hệ thống sẽ hiển thị ảnh chụp màn hình mờ của ứng dụng bạn đã tạm dừng, với thời gian phủ lên trên.
- Trên Wear OS 6 trở lên, nếu một ứng dụng nhắm đến SDK 36 trở lên, thì ứng dụng đó được coi là luôn bật. Màn hình bị mờ, nhưng ứng dụng vẫn tiếp tục chạy và hiển thị. (Các bản cập nhật có thể ít thường xuyên như một lần mỗi phút.)
Tuỳ chỉnh hành vi cho trạng thái Môi trường xung quanh
Bất kể hành vi mặc định của hệ thống, trên tất cả các phiên bản Wear OS, bạn đều có thể tuỳ chỉnh giao diện hoặc hành vi của ứng dụng khi ở trạng thái Môi trường xung quanh bằng cách sử dụng AmbientLifecycleObserver
để nghe các lệnh gọi lại trên các quá trình chuyển đổi trạng thái.
Sử dụng AmbientLifecycleObserver
Để phản ứng với các sự kiện ở chế độ môi trường xung quanh, hãy sử dụng lớp AmbientLifecycleObserver
:
Triển khai giao diện
AmbientLifecycleObserver.AmbientLifecycleCallback
. Sử dụng phương thứconEnterAmbient()
để điều chỉnh giao diện người dùng cho trạng thái tiết kiệm pin vàonExitAmbient()
để khôi phục giao diện người dùng về chế độ hiển thị tương tác đầy đủ.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. } }
Tạo một
AmbientLifecycleObserver
và đăng kýAmbientLifecycleObserver
đó với vòng đời của hoạt động hoặc thành phần kết hợp.private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback) override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) lifecycle.addObserver(ambientObserver) // ... }
Gọi
removeObserver()
để xoá đối tượng tiếp nhận dữ liệu trongonDestroy()
.
Đối với các nhà phát triển sử dụng Jetpack Compose, thư viện Horologist cung cấp một tiện ích hữu ích, thành phần kết hợp AmbientAware
, giúp đơn giản hoá việc triển khai mẫu này.
TimeText nhận biết môi trường xung quanh
Ngoại lệ đối với việc yêu cầu trình quan sát tuỳ chỉnh, trên Wear OS 6, tiện ích TimeText
có thể nhận biết môi trường xung quanh. Trạng thái này tự động cập nhật một lần mỗi phút khi thiết bị ở trạng thái Môi trường xung quanh mà không cần thêm mã nào.
Kiểm soát thời lượng bật màn hình
Các phần sau đây mô tả cách quản lý thời lượng ứng dụng của bạn xuất hiện trên màn hình.
Ngăn việc quay lại mặt đồng hồ khi có Hoạt động đang diễn ra
Sau một khoảng thời gian ở trạng thái Môi trường xung quanh (Giới hạn thời gian #2), hệ thống thường sẽ quay lại mặt đồng hồ. Người dùng có thể định cấu hình thời gian chờ trong phần cài đặt hệ thống. Đối với một số trường hợp sử dụng nhất định, chẳng hạn như người dùng theo dõi một bài tập thể dục, ứng dụng có thể cần hiển thị lâu hơn.
Trên Wear OS 5 trở lên, bạn có thể ngăn điều này bằng cách triển khai Hoạt động đang diễn ra. Nếu ứng dụng của bạn đang hiển thị thông tin về một tác vụ đang diễn ra của người dùng, chẳng hạn như một phiên tập thể dục, thì bạn có thể sử dụng Ongoing Activity API để hiển thị ứng dụng cho đến khi tác vụ kết thúc. Nếu người dùng quay lại mặt đồng hồ theo cách thủ công, thì chỉ báo hoạt động đang diễn ra sẽ cung cấp cách nhấn một lần để họ quay lại ứng dụng của bạn
Để triển khai việc này, ý định chạm của thông báo hiển thị liên tục phải trỏ đến hoạt động luôn bật của bạn, như trong đoạn mã sau:
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() }
Giữ màn hình luôn bật và ngăn trạng thái Môi trường xung quanh
Trong một số ít trường hợp, bạn có thể cần ngăn hoàn toàn thiết bị chuyển sang trạng thái Môi trường xung quanh. Tức là để tránh Thời gian chờ #1. Để làm việc này, bạn có thể sử dụng cờ cửa sổ FLAG_KEEP_SCREEN_ON
. Phương thức này hoạt động như một khoá chế độ thức, giữ cho thiết bị ở trạng thái Tương tác. Hãy sử dụng tính năng này một cách cực kỳ thận trọng vì tính năng này ảnh hưởng nghiêm trọng đến thời lượng pin.
Đề xuất cho Chế độ môi trường xung quanh
Để mang lại trải nghiệm tốt nhất cho người dùng và tiết kiệm pin ở chế độ Môi trường xung quanh, hãy tuân thủ các nguyên tắc thiết kế sau.
- Sử dụng màn hình tối giản, tiêu thụ ít năng lượng
- Giữ ít nhất 85% màn hình màu đen.
- Sử dụng đường viền cho các biểu tượng hoặc nút lớn thay vì màu nền đồng nhất.
- Chỉ hiển thị thông tin quan trọng nhất, di chuyển các chi tiết phụ sang màn hình tương tác.
- Tránh sử dụng các khối màu đồng nhất lớn và hình ảnh thương hiệu hoặc hình nền không mang tính chức năng.
- Đảm bảo nội dung được cập nhật phù hợp
- Đối với dữ liệu thay đổi thường xuyên như đồng hồ bấm giờ, quãng đường tập thể dục hoặc thời gian, hãy hiển thị nội dung giữ chỗ như
--
để tránh tạo ấn tượng rằng nội dung đó là mới. - Xoá các chỉ báo tiến trình cập nhật liên tục, chẳng hạn như đối với chuông đếm ngược và phiên phát nội dung nghe nhìn.
- Bạn chỉ nên sử dụng lệnh gọi lại
onUpdateAmbient()
cho các bản cập nhật cần thiết, thường là một lần mỗi phút.
- Đối với dữ liệu thay đổi thường xuyên như đồng hồ bấm giờ, quãng đường tập thể dục hoặc thời gian, hãy hiển thị nội dung giữ chỗ như
- Duy trì bố cục nhất quán
- Giữ các phần tử ở cùng một vị trí trên chế độ Tương tác và Môi trường xung quanh để tạo hiệu ứng chuyển đổi mượt mà.
- Luôn hiển thị thời gian.
- Nhận biết bối cảnh
- Nếu người dùng đang ở màn hình cài đặt hoặc cấu hình khi thiết bị chuyển sang chế độ môi trường xung quanh, hãy cân nhắc hiển thị một màn hình phù hợp hơn từ ứng dụng thay vì chế độ xem cài đặt.
- Xử lý các yêu cầu theo thiết bị cụ thể
- Trong đối tượng
AmbientDetails
được truyền đếnonEnterAmbient()
:- Nếu
deviceHasLowBitAmbient
làtrue
, hãy tắt tính năng khử răng cưa khi có thể. - Nếu
burnInProtectionRequired
làtrue
, hãy di chuyển các thành phần giao diện người dùng một chút theo định kỳ và tránh các vùng màu trắng đồng nhất để ngăn hiện tượng lưu ảnh trên màn hình.
- Nếu
- Trong đối tượng
Gỡ lỗi và thử nghiệm
Các lệnh adb
này có thể hữu ích khi phát triển hoặc kiểm thử cách ứng dụng của bạn hoạt động khi thiết bị ở chế độ môi trường xung quanh:
# 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
Ví dụ: Ứng dụng tập thể dục
Hãy xem xét một ứng dụng tập thể dục cần hiển thị chỉ số cho người dùng trong toàn bộ thời lượng của phiên tập thể dục. Ứng dụng phải luôn hiển thị trong quá trình chuyển đổi trạng thái Môi trường xung quanh và tránh bị mặt đồng hồ thay thế.
Để đạt được điều này, nhà phát triển nên làm như sau:
- Triển khai
AmbientLifecycleObserver
để xử lý các thay đổi về giao diện người dùng giữa trạng thái Tương tác và Môi trường xung quanh, chẳng hạn như làm mờ màn hình và xoá dữ liệu không cần thiết. - Tạo một bố cục mới có mức tiêu thụ điện năng thấp cho trạng thái Môi trường xung quanh theo các phương pháp hay nhất.
- Sử dụng Ongoing Activity API (API Hoạt động đang diễn ra) trong suốt thời gian tập thể dục để ngăn hệ thống quay lại mặt đồng hồ.
Để triển khai đầy đủ, hãy xem Mẫu bài tập thể dục dựa trên Compose trên GitHub. Mẫu này cũng minh hoạ cách sử dụng thành phần kết hợp AmbientAware
từ thư viện Horologist để đơn giản hoá việc xử lý chế độ môi trường xung quanh trong Compose.