กิจกรรมต่อเนื่อง

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

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

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

เช่น ในแอปออกกำลังกายนี้ ข้อมูลอาจปรากฏบนหน้าปัดนาฬิกาของผู้ใช้เป็นไอคอนการวิ่งที่แตะได้ ดังนี้

ไอคอนการวิ่ง

รูปที่ 1 สัญญาณบอกสถานะกิจกรรม

การแจ้งเตือนต่อเนื่องจะแสดงข้อมูลในส่วนล่าสุดของตัวเปิดแอปส่วนกลางด้วย ซึ่งเป็นอีกที่ที่สะดวกสำหรับผู้ใช้ในการดู สถานะของงานและกลับมามีส่วนร่วมกับแอป

Launcher

รูปที่ 2 Launcher ส่วนกลาง

สถานการณ์ที่ควรใช้การแจ้งเตือนต่อเนื่องที่เชื่อมโยงกับกิจกรรมต่อเนื่องมีดังนี้

ตัวจับเวลา

รูปที่ 3 ตัวจับเวลา: นับเวลาถอยหลังและสิ้นสุดเมื่อตัวจับเวลา หยุดชั่วคราวหรือหยุด

แผนที่

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

เพลง

รูปที่ 5 สื่อ: เปิดเพลงตลอดเซสชัน สิ้นสุดทันที หลังจากที่ผู้ใช้หยุดเซสชันชั่วคราว

Wear จะสร้างกิจกรรมต่อเนื่องสำหรับแอปสื่อโดยอัตโนมัติ

ดูตัวอย่างโดยละเอียดเกี่ยวกับการสร้าง กิจกรรมต่อเนื่องสำหรับแอปประเภทอื่นๆ ได้ที่ Codelab กิจกรรมต่อเนื่อง

ตั้งค่า

หากต้องการเริ่มใช้ Ongoing Activity API ในแอป ให้เพิ่มการอ้างอิงต่อไปนี้ลงในไฟล์ build.gradle ของแอป

dependencies {
  implementation "androidx.wear:wear-ongoing:1.1.0"
  implementation "androidx.core:core:1.17.0"
}

สร้างกิจกรรมต่อเนื่อง

กระบวนการนี้มี 3 ขั้นตอนดังนี้

  1. สร้าง NotificationCompat.Builder มาตรฐานและกำหนดค่าเป็น ต่อเนื่อง
  2. สร้างและกำหนดค่าออบเจ็กต์ OngoingActivity โดยส่งเครื่องมือสร้างการแจ้งเตือนไปยังออบเจ็กต์
  3. ใช้กิจกรรมต่อเนื่องกับเครื่องมือสร้างการแจ้งเตือนและโพสต์ การแจ้งเตือนที่ได้

สร้างและกำหนดค่าการแจ้งเตือน

เริ่มต้นด้วยการสร้าง NotificationCompat.Builder ขั้นตอนสำคัญคือการเรียกใช้ setOngoing(true) เพื่อทำเครื่องหมายเป็นการแจ้งเตือนต่อเนื่อง นอกจากนี้ คุณยังตั้งค่าพร็อพเพอร์ตี้การแจ้งเตือนอื่นๆ ในขั้นตอนนี้ได้ด้วย เช่น ไอคอนขนาดเล็กและหมวดหมู่

// Create a PendingIntent to pass to the notification builder
val pendingIntent =
    PendingIntent.getActivity(
        this,
        0,
        Intent(this, AlwaysOnActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        },
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
    )

val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("Always On Service")
    .setContentText("Service is running in background")
    .setSmallIcon(R.drawable.animated_walk)
    // Category helps the system prioritize the ongoing activity
    .setCategory(NotificationCompat.CATEGORY_WORKOUT)
    .setContentIntent(pendingIntent)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .setOngoing(true) // Important!

สร้าง OngoingActivity

จากนั้นสร้างอินสแตนซ์ของ OngoingActivity โดยใช้เครื่องมือสร้าง OngoingActivity.Builder ต้องมี Context, รหัสการแจ้งเตือน และ NotificationCompat.Builder ที่คุณสร้างไว้ในขั้นตอนก่อนหน้า

กำหนดค่าพร็อพเพอร์ตี้หลักที่จะแสดงในแพลตฟอร์ม UI ใหม่ ดังนี้

  • ไอคอนแบบเคลื่อนไหวและแบบคงที่: ระบุไอคอนที่จะแสดงบนหน้าปัดนาฬิกาในโหมดแอ็กทีฟและโหมดแอมเบียนท์
  • Touch Intent: PendingIntent ที่นำผู้ใช้กลับมายังแอปเมื่อแตะไอคอนกิจกรรมต่อเนื่อง คุณสามารถใช้ pendingIndent ที่สร้างไว้ในขั้นตอนก่อนหน้าซ้ำได้

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // Sets the icon that appears on the watch face in active mode.
        .setAnimatedIcon(R.drawable.animated_walk)
        // Sets the icon that appears on the watch face in ambient mode.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap target to bring the user back to the app.
        .setTouchIntent(pendingIntent)
        .build()

ใช้กับการแจ้งเตือนและโพสต์

ขั้นตอนสุดท้ายคือการลิงก์ OngoingActivity กับการแจ้งเตือน แล้วโพสต์ เมธอด ongoingActivity.apply() จะแก้ไขเครื่องมือสร้างการแจ้งเตือนเดิม โดยเพิ่มข้อมูลที่จำเป็นเพื่อให้ระบบแสดงการแจ้งเตือนใน แพลตฟอร์มอื่นๆ ได้ หลังจากใช้แล้ว คุณจะสร้างและโพสต์การแจ้งเตือนได้ตามปกติ

// This call modifies notificationBuilder to include the ongoing activity data.
ongoingActivity.apply(applicationContext)

// Post the notification.
startForeground(NOTIFICATION_ID, notificationBuilder.build())

เพิ่มข้อความสถานะแบบไดนามิกลงใน Launcher

โค้ดข้างต้นจะเพิ่มไอคอนที่แตะได้ลงในหน้าปัดนาฬิกา หากต้องการให้การอัปเดตในส่วนล่าสุดของ Launcher มีความสมบูรณ์และเป็นแบบเรียลไทม์ยิ่งขึ้น ให้สร้างออบเจ็กต์ Status แล้วแนบไปกับ OngoingActivity หากคุณไม่ระบุ Status ที่กำหนดเอง ระบบจะใช้ข้อความเนื้อหาของการแจ้งเตือนเป็นค่าเริ่มต้น (ตั้งค่าโดยใช้ setContentText()) หากต้องการแสดงข้อความแบบไดนามิก ให้ใช้ Status.Builder คุณสามารถกำหนดสตริงเทมเพลตด้วยตัวยึดตำแหน่งและระบุออบเจ็กต์ Status.Part เพื่อเติมตัวยึดตำแหน่งเหล่านั้น Status.Part อาจเป็นแบบไดนามิก เช่น นาฬิกาจับเวลาหรือตัวจับเวลา

ตัวอย่างต่อไปนี้แสดงวิธีสร้างสถานะที่แสดงข้อความว่า "วิ่งเป็นเวลา [ตัวจับเวลาของนาฬิกา]"

// Define a template with placeholders for the activity type and the timer.
val statusTemplate = "#type# for #time#"

// Set the start time for a stopwatch.
// Use SystemClock.elapsedRealtime() for time-based parts.
val runStartTime = SystemClock.elapsedRealtime()

val ongoingActivityStatus = Status.Builder()
    // Sets the template string.
    .addTemplate(statusTemplate)
    // Fills the #type# placeholder with a static text part.
    .addPart("type", Status.TextPart("Run"))
    // Fills the #time# placeholder with a stopwatch part.
    .addPart("time", Status.StopwatchPart(runStartTime))
    .build()

สุดท้าย ให้ลิงก์ Status นี้กับ OngoingActivity โดยเรียกฟังก์ชัน setStatus() ใน OngoingActivity.Builder

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // ...
        // Add the status to the OngoingActivity.
        .setStatus(ongoingActivityStatus)
        .build()

การปรับแต่งเพิ่มเติม

นอกเหนือจาก Status แล้ว คุณยังปรับแต่งกิจกรรมหรือการแจ้งเตือนต่อเนื่องได้ด้วยวิธีต่อไปนี้ อย่างไรก็ตาม ระบบอาจไม่ใช้การปรับแต่งเหล่านี้ ทั้งนี้ขึ้นอยู่กับการติดตั้งใช้งานของ OEM

การแจ้งเตือนต่อเนื่อง

  • หมวดหมู่ที่ตั้งค่าไว้จะกำหนดลำดับความสำคัญของกิจกรรมต่อเนื่อง
    • CATEGORY_CALL: การโทรด้วยเสียงหรือวิดีโอคอลขาเข้า หรือคำขอสื่อสารแบบซิงโครนัสที่คล้ายกัน
    • CATEGORY_NAVIGATION: แผนที่หรือการนำทางแบบเลี้ยวต่อเลี้ยว
    • CATEGORY_TRANSPORT: การควบคุมการส่งผ่านสื่อสำหรับการเล่น
    • CATEGORY_ALARM: การปลุกหรือตัวจับเวลา
    • CATEGORY_WORKOUT: การออกกำลังกาย
    • CATEGORY_LOCATION_SHARING: หมวดหมู่การแชร์ตำแหน่งชั่วคราว
    • CATEGORY_STOPWATCH: นาฬิกาจับเวลา

กิจกรรมต่อเนื่อง

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

  • ไอคอนภาพนิ่ง: ไอคอนเวกเตอร์ที่มีพื้นหลังโปร่งใส แสดงบน หน้าปัดในโหมดแอมเบียนท์ หากไม่ได้ตั้งค่าไอคอนเคลื่อนไหว ระบบจะใช้ไอคอนภาพนิ่งบนหน้าปัดในโหมดแอ็กทีฟ หากไม่ได้ระบุ ระบบจะใช้ไอคอนการแจ้งเตือน หากไม่ได้ตั้งค่าใดไว้ ระบบจะแสดงข้อยกเว้น (ตัวเปิดแอปยังคงใช้ไอคอนแอป)

  • OngoingActivityStatus: ข้อความธรรมดาหรือ Chronometer แสดงในส่วนล่าสุดของตัวเปิดแอป หากไม่ได้ระบุ ระบบจะใช้ "ข้อความบริบท" ของการแจ้งเตือน

  • Touch Intent: PendingIntent ใช้เพื่อสลับกลับไปที่แอปหากผู้ใช้แตะไอคอนกิจกรรมต่อเนื่อง แสดงบนหน้าปัดหรือในรายการของ Launcher โดยอาจแตกต่างจาก Intent เดิมที่ใช้เปิดแอป หากไม่ได้ระบุไว้ ระบบจะใช้ Intent เนื้อหาของการแจ้งเตือน หากไม่ได้ตั้งค่าทั้ง 2 อย่าง ระบบจะแสดงข้อยกเว้น

  • LocusId: รหัสที่กำหนดทางลัดของ Launcher ที่สอดคล้องกับกิจกรรมต่อเนื่อง แสดงใน Launcher ในส่วนล่าสุด ขณะที่กิจกรรมกำลังดำเนินอยู่ หากไม่ได้ระบุไว้ Launcher จะซ่อนรายการแอปทั้งหมดในส่วนล่าสุดจากแพ็กเกจเดียวกัน และแสดงเฉพาะกิจกรรมต่อเนื่อง

  • รหัสกิจกรรมต่อเนื่อง: รหัสที่ใช้เพื่อแยกความแตกต่างของการเรียกฟังก์ชัน fromExistingOngoingActivity() เมื่อแอปพลิเคชันมีกิจกรรมต่อเนื่องมากกว่า 1 รายการ

อัปเดตกิจกรรมต่อเนื่อง

ในกรณีส่วนใหญ่ นักพัฒนาแอปจะสร้างการแจ้งเตือนต่อเนื่องใหม่และกิจกรรมต่อเนื่องใหม่เมื่อต้องการอัปเดตข้อมูลบนหน้าจอ อย่างไรก็ตาม Ongoing Activity API ยังมีเมธอดตัวช่วยในการอัปเดต OngoingActivity หากคุณ ต้องการเก็บอินสแตนซ์ไว้แทนที่จะสร้างใหม่

หากแอปทำงานในเบื้องหลัง แอปจะส่งข้อมูลอัปเดตไปยัง Ongoing Activity API ได้ อย่างไรก็ตาม ไม่ควรอัปเดตบ่อยเกินไป เนื่องจากเมธอดการอัปเดตจะไม่สนใจการเรียกที่อยู่ใกล้กันมากเกินไป การอัปเดต 2-3 ครั้งต่อนาทีถือเป็น เรื่องปกติ

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

ongoingActivity.update(context, newStatus)

เรามีเมธอดแบบคงที่เพื่อสร้างกิจกรรมต่อเนื่องเพื่อความสะดวก

OngoingActivity.recoverOngoingActivity(context)
               .update(context, newStatus)

หยุดกิจกรรมต่อเนื่อง

เมื่อแอปทำงานเป็นกิจกรรมต่อเนื่องเสร็จแล้ว แอปจะต้องยกเลิก การแจ้งเตือนต่อเนื่องเท่านั้น

นอกจากนี้ คุณยังเลือกยกเลิกการแจ้งเตือนหรือกิจกรรมต่อเนื่องได้เมื่อแอปเข้าสู่เบื้องหน้า แล้วสร้างใหม่เมื่อกลับไปที่เบื้องหลัง แต่ไม่จำเป็นต้องทำ

หยุดกิจกรรมต่อเนื่องชั่วคราว

หากแอปมีการดำเนินการหยุดอย่างชัดเจน ให้ทำกิจกรรมต่อเนื่องต่อหลังจากที่กลับมาทำงานอีกครั้ง สำหรับแอปที่ไม่มีการดำเนินการหยุดอย่างชัดเจน ให้สิ้นสุดกิจกรรมเมื่อ หยุดชั่วคราว

แนวทางปฏิบัติแนะนำ

โปรดคำนึงถึงสิ่งต่อไปนี้เมื่อทำงานกับ Ongoing Activity API

  • ตั้งค่าไอคอนภาพนิ่งสำหรับกิจกรรมต่อเนื่อง ไม่ว่าจะระบุอย่างชัดเจนหรือใช้การแจ้งเตือนเป็นค่าสำรอง หากไม่ทำ คุณจะได้รับ IllegalArgumentException

  • ใช้ไอคอนเวกเตอร์ขาวดำที่มีพื้นหลังโปร่งใส

  • ตั้งค่า Touch Intent สำหรับกิจกรรมต่อเนื่อง ไม่ว่าจะระบุอย่างชัดเจนหรือใช้การแจ้งเตือนเป็นค่าสำรอง หากไม่ทำ คุณจะได้รับ IllegalArgumentException

  • หากแอปมีกิจกรรม MAIN LAUNCHER มากกว่า 1 รายการที่ประกาศไว้ในไฟล์ Manifest ให้เผยแพร่ทางลัดแบบไดนามิกและเชื่อมโยงกับกิจกรรมต่อเนื่องโดยใช้ LocusId

เผยแพร่การแจ้งเตือนสื่อเมื่อเล่นสื่อในอุปกรณ์ Wear OS

หากมีการเล่นเนื้อหาสื่อในอุปกรณ์ Wear OS ให้เผยแพร่การแจ้งเตือนสื่อ ซึ่งจะช่วยให้ระบบสร้างกิจกรรมต่อเนื่องที่เกี่ยวข้องได้

หากคุณใช้ Media3 ระบบจะเผยแพร่การแจ้งเตือนโดยอัตโนมัติ หากสร้างการแจ้งเตือนด้วยตนเอง การแจ้งเตือนนั้นควรใช้ MediaStyleNotificationHelper.MediaStyle และ MediaSession ที่เกี่ยวข้องควรมีกิจกรรมในเซสชันที่สร้างขึ้น