แอปที่เปิดตลอดเวลาและโหมดแอมเบียนท์ของระบบ

คู่มือนี้อธิบายวิธีทำให้แอปทำงานตลอดเวลา วิธีตอบสนองต่อการเปลี่ยนสถานะพลังงาน และวิธีจัดการลักษณะการทำงานของแอปพลิเคชันเพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีขณะประหยัดแบตเตอรี่

การทำให้แอปมองเห็นได้ตลอดเวลาจะส่งผลต่อระยะเวลาการใช้งานแบตเตอรี่อย่างมาก ดังนั้นโปรดพิจารณา ผลกระทบด้านพลังงานเมื่อเพิ่มฟีเจอร์นี้

หัวข้อสำคัญ

เมื่อแอป Wear OS แสดงแบบเต็มหน้าจอ แอปจะอยู่ในสถานะพลังงาน 2 สถานะต่อไปนี้

  • โต้ตอบได้: สถานะที่มีการใช้พลังงานสูงซึ่งหน้าจอมีความสว่างสูงสุด เพื่อให้ผู้ใช้โต้ตอบได้อย่างเต็มที่
  • โดยรอบ: สถานะพลังงานต่ำที่จอแสดงผลจะหรี่แสงเพื่อประหยัดพลังงาน ใน สถานะนี้ UI ของแอปยังคงใช้พื้นที่เต็มหน้าจอ แต่ระบบ อาจเปลี่ยนลักษณะที่ปรากฏโดยการเบลอหรือซ้อนทับเนื้อหา เช่น เวลา ซึ่งเรียกอีกอย่างว่าโหมดแอมเบียนท์

ระบบปฏิบัติการจะควบคุมการเปลี่ยนสถานะระหว่างสถานะเหล่านี้

แอปที่เปิดตลอดเวลาคือแอปพลิเคชันที่แสดงเนื้อหาทั้งในสถานะโต้ตอบและแอมเบียนท์

เมื่อแอปที่เปิดอยู่ตลอดเวลาแสดง UI ของตัวเองต่อไปขณะที่อุปกรณ์อยู่ในสถานะแอมเบียนท์ที่ใช้พลังงานต่ำ เราจะเรียกว่าอยู่ในโหมดแอมเบียแอ็กทีฟ

การเปลี่ยนระบบและลักษณะการทำงานเริ่มต้น

เมื่อแอปอยู่เบื้องหน้า ระบบจะจัดการการเปลี่ยนสถานะพลังงาน ตามการหมดเวลา 2 รายการที่เกิดจากการที่ผู้ใช้ไม่ได้ใช้งาน

  • หมดเวลา #1: สถานะโต้ตอบเป็นสถานะแวดล้อม: หลังจากที่ผู้ใช้ไม่ได้ใช้งานเป็นระยะเวลาหนึ่ง อุปกรณ์จะเข้าสู่สถานะแวดล้อม
  • หมดเวลา #2: กลับไปที่หน้าปัด: หลังจากไม่มีการใช้งานอีกระยะหนึ่ง ระบบอาจซ่อนแอปปัจจุบันและแสดงหน้าปัด

ทันทีหลังจากที่ระบบเปลี่ยนสถานะเป็น รอบข้างเป็นครั้งแรก ลักษณะการทำงานเริ่มต้นจะขึ้นอยู่กับเวอร์ชัน Wear OS และการกำหนดค่าของแอป

  • ใน Wear OS 5 และเวอร์ชันที่ต่ำกว่า ระบบจะแสดงภาพหน้าจอที่เบลอของแอปพลิเคชันที่หยุดชั่วคราว โดยมีเวลาซ้อนทับอยู่ด้านบน
  • ใน Wear OS 6 ขึ้นไป หากแอปกำหนดเป้าหมายเป็น SDK 36 ขึ้นไป ระบบจะถือว่าแอป เปิดอยู่เสมอ จอแสดงผลจะหรี่แสงลง แต่แอปพลิเคชันจะยังทำงานต่อไปและยังคงมองเห็นได้ (การอัปเดตอาจเกิดขึ้นนานๆ ครั้ง เช่น ทุกๆ 1 นาที)

ปรับแต่งลักษณะการทำงานสำหรับสถานะแอมเบียนท์

ไม่ว่าลักษณะการทำงานของระบบเริ่มต้นจะเป็นอย่างไร คุณสามารถปรับแต่งลักษณะหรือลักษณะการทำงานของแอปขณะอยู่ในสถานะแอมเบียนท์ได้ใน Wear OS ทุกเวอร์ชันโดยใช้ AmbientLifecycleObserver เพื่อฟังการเรียกกลับในการเปลี่ยนสถานะ

ใช้ 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 และลงทะเบียนด้วยวงจรของ กิจกรรมหรือ Composable

    private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback)
    
    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(ambientObserver)
    
        // ...
    }
    
  3. โทรหา removeObserver() เพื่อนำผู้สังเกตการณ์ใน onDestroy() ออก

สำหรับนักพัฒนาแอปที่ใช้ Jetpack Compose ไลบรารี Horologist มี ยูทิลิตีที่มีประโยชน์คือ Composable AmbientAware ซึ่งช่วยลดความซับซ้อนในการใช้งาน รูปแบบนี้

TimeText ที่รับรู้บรรยากาศโดยรอบ

ใน Wear OS 6 TimeText วิดเจ็ตจะรับรู้ถึงโหมดแอมเบียนท์ ซึ่งเป็นข้อยกเว้นที่ไม่ต้องใช้ Observer ที่กำหนดเอง โดยจะอัปเดตโดยอัตโนมัติทุกนาทีเมื่ออุปกรณ์อยู่ในสถานะรอบข้างโดยไม่ต้องใช้โค้ดเพิ่มเติม

ควบคุมระยะเวลาการเปิดหน้าจอ

ส่วนต่อไปนี้อธิบายวิธีจัดการระยะเวลาที่แอปจะแสดงบนหน้าจอ

ป้องกันการกลับไปที่หน้าปัดด้วยกิจกรรมที่กำลังดำเนินอยู่

หลังจากอยู่ในสถานะโดยรอบเป็นระยะเวลาหนึ่ง (หมดเวลา #2) โดยปกติแล้วระบบจะ กลับไปที่หน้าปัด ผู้ใช้สามารถกำหนดค่าระยะหมดเวลาได้ ในการตั้งค่าระบบ ในบางกรณี เช่น ผู้ใช้ติดตามการออกกำลังกาย แอปอาจต้องแสดงต่อไปนานขึ้น

ใน Wear OS 5 ขึ้นไป คุณป้องกันปัญหานี้ได้โดยการใช้ Ongoing Activity หากแอปแสดงข้อมูลเกี่ยวกับงานของผู้ใช้ที่กำลังดำเนินการอยู่ เช่น เซสชันการออกกำลังกาย คุณสามารถใช้ 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 ได้ ซึ่งจะทำหน้าที่เป็นการล็อกการปลุกเพื่อให้อุปกรณ์อยู่ในสถานะโต้ตอบ โปรดใช้ตัวเลือกนี้ด้วยความระมัดระวังอย่างยิ่ง เนื่องจากจะ ส่งผลต่ออายุการใช้งานแบตเตอรี่อย่างมาก

คำแนะนำสำหรับโหมดแอมเบียนท์

โปรดปฏิบัติตามหลักเกณฑ์การออกแบบเหล่านี้เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีที่สุดและประหยัดพลังงานในโหมดรอบข้าง คำแนะนำเหล่านี้ให้ความสำคัญกับประสบการณ์ของผู้ใช้ที่ชัดเจน โดยป้องกันข้อมูลที่ทำให้เข้าใจผิดและลดความซับซ้อนของภาพ พร้อมทั้งเพิ่มประสิทธิภาพการแสดงผลไปพร้อมกัน

  • ลดความรกของภาพและเพิ่มพลังการแสดงผล UI ที่เรียบง่ายและมินิมอลจะส่งสัญญาณ ให้ผู้ใช้ทราบว่าแอปอยู่ในสถานะพลังงานต่ำและประหยัด แบตเตอรี่ได้อย่างมากด้วยการจำกัดพิกเซลสว่าง
    • ให้หน้าจอเป็นสีดำอย่างน้อย 85%
    • แสดงเฉพาะข้อมูลที่สำคัญที่สุด และย้ายรายละเอียดรองไปไว้ที่ จอแสดงผลแบบอินเทอร์แอกทีฟ
    • ใช้เส้นขอบสำหรับไอคอนหรือปุ่มขนาดใหญ่แทนการเติมสีทึบ
    • หลีกเลี่ยงการใช้สีทึบเป็นบล็อกขนาดใหญ่และแบรนด์หรือ ภาพพื้นหลังที่ใช้งานไม่ได้
  • จัดการข้อมูลแบบไดนามิกที่ล้าสมัย
    • ระบบจะเรียกใช้การเรียกกลับ onUpdateAmbient() เป็นระยะๆ เท่านั้น โดยปกติจะเรียกใช้ 1 ครั้งต่อนาที เพื่อประหยัดพลังงาน เนื่องจากข้อจำกัดนี้ ข้อมูลที่มีการเปลี่ยนแปลงบ่อยครั้ง เช่น นาฬิกาจับเวลา อัตราการเต้นของหัวใจ หรือระยะทางการออกกำลังกาย จะล้าสมัยระหว่างการอัปเดต หากต้องการหลีกเลี่ยงการแสดงข้อมูลที่ไม่ถูกต้องและทำให้เข้าใจผิด ให้รอonEnterAmbientการเรียกกลับ และแทนที่ค่าแบบเรียลไทม์เหล่านี้ด้วยเนื้อหาตัวยึดตำแหน่งแบบคงที่ เช่น --
  • คงเลย์เอาต์ให้สอดคล้องกัน
    • วางองค์ประกอบในตำแหน่งเดียวกันในโหมดอินเทอร์แอกทีฟและแอมเบียนท์ เพื่อสร้างการเปลี่ยนผ่านที่ราบรื่น
    • แสดงเวลาเสมอ
  • คำนึงถึงบริบท
    • หากผู้ใช้อยู่ในหน้าจอการตั้งค่าหรือการกำหนดค่าเมื่ออุปกรณ์ เข้าสู่โหมดแอมเบียนท์ ให้พิจารณาแสดงหน้าจอที่เกี่ยวข้องมากขึ้นจากแอป แทนมุมมองการตั้งค่า
  • จัดการข้อกำหนดเฉพาะของอุปกรณ์
    • ในออบเจ็กต์ AmbientDetails ที่ส่งไปยัง onEnterAmbient() ให้ทำดังนี้
      • หาก deviceHasLowBitAmbient เป็น true ให้ปิดใช้การลบรอยหยักหากเป็นไปได้
      • หาก burnInProtectionRequired เป็น true ให้เลื่อนองค์ประกอบ 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 ตลอดระยะเวลาการออกกำลังกายเพื่อป้องกันไม่ให้ระบบกลับไปที่หน้าปัด

ดูการใช้งานที่สมบูรณ์ได้ในตัวอย่างการออกกำลังกายที่อิงตาม Compose ใน GitHub ตัวอย่างนี้ยังแสดงการใช้ AmbientAware ที่ประกอบได้จากไลบรารี Horologist เพื่อลดความซับซ้อนในการจัดการโหมดแอมเบียนท์ ใน Compose