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

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

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

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

running-icon

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

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

Launcher

รูปที่ 2 ตัวเรียกใช้ส่วนกลาง

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

ตัวจับเวลา

รูปที่ 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 โดยส่ง Notification Builder ไปยังออบเจ็กต์
  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 ใหม่ ดังนี้

  • ไอคอนแบบเคลื่อนไหวและแบบคงที่: ระบุไอคอนที่จะแสดงบนหน้าปัดนาฬิกาในโหมดใช้งานและโหมดแอมเบียนท์
  • ความตั้งใจในการแตะ: 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อาจเป็นแบบไดนามิก เช่น นาฬิกาจับเวลาหรือตัวจับเวลา

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

// 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)
    • CATEGORY_STOPWATCH: นาฬิกาจับเวลา

กิจกรรมที่กำลังดำเนินอยู่

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

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

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

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

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

  • รหัสกิจกรรมที่กำลังดำเนินอยู่: รหัสที่ใช้เพื่อแยกความแตกต่างของการเรียกไปยัง 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

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

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

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

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

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

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