การใช้การแจ้งเตือนของ Android

Codelab นี้เป็นส่วนหนึ่งของหลักสูตร Android ขั้นสูงใน Kotlin คุณจะได้รับประโยชน์สูงสุดจากหลักสูตรนี้หากทำตาม Codelab ตามลำดับ แต่ไม่จำเป็นต้องทำ Codelab ของหลักสูตรทั้งหมดแสดงอยู่ในหน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin

บทนำ

การแจ้งเตือนคือข้อความที่แสดงต่อผู้ใช้นอก UI ของแอป การแจ้งเตือนจะแสดงที่ด้านบนของหน้าจอหากอุปกรณ์ปลดล็อกอยู่ หรือจะแสดงบนหน้าจอล็อกเมื่ออุปกรณ์ล็อกอยู่ ทั้งนี้ขึ้นอยู่กับการตั้งค่าความปลอดภัย

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

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

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

ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีสร้างและใช้การแจ้งเตือนในแอป Android

สิ่งที่คุณควรทราบอยู่แล้ว

คุณควรคุ้นเคยกับสิ่งต่อไปนี้

  • วิธีสร้างแอป Android ใน Kotlin โดยเฉพาะอย่างยิ่ง ให้ทำงานกับ Android SDK
  • วิธีออกแบบแอปโดยใช้ Architecture Components และการเชื่อมโยงข้อมูล
  • ความเข้าใจพื้นฐานเกี่ยวกับ BroadcastReceiver
  • ความเข้าใจพื้นฐานเกี่ยวกับ AlarmManager

สิ่งที่คุณจะได้เรียนรู้

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

สิ่งที่คุณต้องดำเนินการ

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

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

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

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

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

โคลนที่เก็บจาก GitHub แล้วเปลี่ยนไปที่สาขา starter

$  git clone https://github.com/googlecodelabs/android-kotlin-notifications


หรือคุณจะดาวน์โหลดที่เก็บเป็นไฟล์ Zip, แตกไฟล์ และเปิดใน Android Studio ก็ได้

ดาวน์โหลด Zip

  1. เปิดและเรียกใช้แอปใน Android Studio

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

  1. ตรวจสอบซอร์สโค้ด แอปเริ่มต้นประกอบด้วยกิจกรรมเดียวชื่อ MainActivity โดยมีแพ็กเกจย่อย 3 แพ็กเกจชื่อ receiver, ui และ util

  • /receiver - แพ็กเกจ receiver มี Broadcast Receiver 2 รายการชื่อ AlarmReceiver และ SnoozeReceiver AlarmReceiver จะทริกเกอร์ AlarmManager เพื่อส่งการแจ้งเตือนเมื่อตัวจับเวลาที่ผู้ใช้กำหนดหมดเวลา SnoozeReceiver จัดการการคลิกของผู้ใช้เพื่อเลื่อนการแจ้งเตือน
  • /ui - มี EggTimerFragment ซึ่งเป็นส่วนหนึ่งของส่วน UI ของแอป EggTimerViewModel มีหน้าที่เริ่มและยกเลิกตัวจับเวลา รวมถึงจัดการงานอื่นๆ ของแอปที่เกี่ยวข้องกับวงจร
  • /util - ในแพ็กเกจนี้มี 2 ไฟล์ BindingUtils.kt มี Binding Adapter เพื่อเปิดใช้การเชื่อมโยงข้อมูลระหว่าง UI ของแอปกับ ViewModel NotificationUtils.kt มีวิธีการขยายเวลาใน NotificationManager

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

ขั้นตอนที่ 1: สร้างการแจ้งเตือนพื้นฐาน

ในงานนี้ คุณจะสร้างการแจ้งเตือนใหม่ ตั้งค่าข้อความสำหรับผู้ใช้ และส่งการแจ้งเตือน

  1. เปิดNotificationUtils.ktชั้นเรียนTODO: Step 1.1 แล้วค้นหา คุณจะเห็นสิ่งที่ต้องทำที่ตรงกันในโค้ดแล็บนี้และโค้ดของแอป
  2. ตรวจสอบฟังก์ชัน sendNotification() ที่ระบุ คุณจะขยายฟังก์ชันส่วนขยายนี้ไปยัง NotificationManager เพื่อส่งการแจ้งเตือน
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
 * Builds and delivers a notification.
 *
 * @param messageBody, notification text.
 * @param context, activity context.
 */
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
  1. รับอินสแตนซ์ของเครื่องมือสร้างการแจ้งเตือน ส่งบริบทของแอปและรหัสแชแนล รหัสช่องคือค่าสตริงสำหรับช่อง

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

//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
        applicationContext,
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. ตั้งค่าไอคอนการแจ้งเตือนให้แสดงถึงแอปของคุณ ชื่อ และข้อความเนื้อหาสำหรับข้อความที่คุณต้องการส่งให้ผู้ใช้ คุณจะเห็นตัวเลือกเพิ่มเติมในการปรับแต่งการแจ้งเตือนในโค้ดแล็บ แต่ข้อมูลนี้เป็นจำนวนขั้นต่ำที่คุณต้องตั้งค่าเพื่อส่งการแจ้งเตือน
//NotificationUtils.kt
   // TODO: Step 1.3 set title, text and icon to builder
   .setSmallIcon(R.drawable.cooked_egg)
   .setContentTitle(applicationContext.getString(R.string.notification_title))
   .setContentText(messageBody)
  1. จากนั้นคุณต้องเรียกใช้ notify() โดยใช้รหัสที่ไม่ซ้ำกันสำหรับการแจ้งเตือนและใช้ออบเจ็กต์ Notification จากบิลเดอร์

รหัสนี้แสดงถึงอินสแตนซ์การแจ้งเตือนปัจจุบันและจำเป็นสำหรับการอัปเดตหรือยกเลิกการแจ้งเตือนนี้ เนื่องจากแอปจะมีเพียงการแจ้งเตือนที่ใช้งานอยู่ 1 รายการในเวลาใดก็ตาม คุณจึงใช้รหัสเดียวกันสำหรับการแจ้งเตือนทั้งหมดได้ คุณได้รับค่าคงที่เพื่อวัตถุประสงค์นี้แล้ว ซึ่งเรียกว่า NOTIFICATION_ID ใน NotificationUtils.kt โปรดสังเกตว่าคุณสามารถเรียกใช้ notify() ได้โดยตรงเนื่องจากคุณเรียกใช้จากฟังก์ชันส่วนขยายในคลาสเดียวกัน

//NotificationUtils.kt
   // TODO: Step 1.4 call notify to send the notification
    // Deliver the notification
    notify(NOTIFICATION_ID, builder.build())
  1. เปิด ui/EggTimerViewModel.kt แล้วค้นหาฟังก์ชัน startTimer() ฟังก์ชันนี้จะสร้างการปลุกที่มีช่วงเวลาที่เลือกเมื่อผู้ใช้เปิดใช้ตัวจับเวลาไข่
  2. คุณจะทริกเกอร์การแจ้งเตือนในฟังก์ชันนี้เมื่อผู้ใช้เริ่มตัวจับเวลา หากต้องการเรียกใช้ฟังก์ชัน sendNotification() ที่คุณติดตั้งใช้งานไว้ก่อนหน้านี้ คุณต้องมีอินสแตนซ์ของ NotificationManager NotificationManager เป็นบริการของระบบที่ให้ฟังก์ชันทั้งหมดที่เปิดเผยสำหรับ Notifications API รวมถึงฟังก์ชันส่วนขยายที่คุณเพิ่ม เมื่อใดก็ตามที่คุณต้องการส่ง ยกเลิก หรืออัปเดตการแจ้งเตือน คุณจะต้องขออินสแตนซ์ของ NotificationManager จากระบบ เรียกใช้sendNotification()|ฟังก์ชันพร้อมข้อความแจ้งเตือนและบริบท
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification

val notificationManager = ContextCompat.getSystemService(
    app, 
    NotificationManager::class.java
) as NotificationManager
                notificationManager.sendNotification(app.getString(R.string.timer_running), app)

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

  1. เปิด logcat แล้วค้นหา "No Channel found" คุณควรเห็นข้อความแสดงข้อผิดพลาดว่าไม่มี egg_channel ในขั้นตอนต่อไปนี้ คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับช่องทางการแจ้งเตือนและแก้ไขปัญหานี้

ขั้นตอนที่ 2: ช่องทางการแจ้งเตือน

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

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

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

ในขั้นตอนที่ 1.1 คุณใช้ egg_notification_channel_id เป็นช่องทางการแจ้งเตือน ดังนั้นตอนนี้คุณต้องสร้างและปรับแต่งการตั้งค่าการแจ้งเตือนและลักษณะการทำงานของช่องนี้จริงๆ

  1. เปิด EggTimerFragment.kt แล้วค้นหาฟังก์ชัน createChannel()
  2. ส่งรหัสช่องที่ไม่ซ้ำกันไปยังตัวสร้างของ NotificationChannel
  3. ส่งชื่อแชแนลการแจ้งเตือน ซึ่งผู้ใช้จะเห็นในหน้าจอการตั้งค่าด้วย
  4. ส่งระดับความสำคัญสำหรับช่องทางการแจ้งเตือนเป็นพารามิเตอร์สุดท้าย เราจะพูดถึงระดับความสำคัญในภายหลังในโค้ดแล็บนี้ ดังนั้นตอนนี้คุณสามารถใช้ NotificationManager.IMPORTANCE_LOW ได้
  5. ในออบเจ็กต์ notificationChannel ให้ตั้งค่า enableLights เป็น true การตั้งค่านี้จะเปิดไฟเมื่อมีการแสดงการแจ้งเตือน
  6. ตั้งค่า notificationChannel object set lightColor เป็นสีแดงเพื่อแสดงไฟสีแดงเมื่อมีการแจ้งเตือน
  7. ในออบเจ็กต์ notificationChannel ให้ตั้งค่า enableVibration เป็น true เพื่อเปิดใช้การสั่น
  8. ในออบเจ็กต์ notificationChannel ให้ตั้งค่าคำอธิบายช่องเป็น ‘Time for breakfast'
  9. รับอินสแตนซ์ของ NotificationManager โดยโทรหา getSystemService()
  10. เรียกใช้ createNotificationChannel() ใน NotificationManager และส่งออบเจ็กต์ notificationChannel ที่คุณสร้างไว้ในขั้นตอนก่อนหน้า
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
    // TODO: Step 1.6 START create a channel
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val notificationChannel = NotificationChannel(
            channelId,
            channelName,
            // TODO: Step 2.4 change importance
            NotificationManager.IMPORTANCE_LOW
        )
        // TODO: Step 2.6 disable badges for this channel

        notificationChannel.enableLights(true)
        notificationChannel.lightColor = Color.RED
        notificationChannel.enableVibration(true)
        notificationChannel.description = "Time for breakfast"

        val notificationManager = requireActivity().getSystemService(
            NotificationManager::class.java
        )
        notificationManager.createNotificationChannel(notificationChannel)
    }
    // TODO: Step 1.6 END create channel
}
  1. จากนั้น หากต้องการสร้างช่อง คุณต้องเรียกใช้ฟังก์ชัน createChannel() ที่คุณเพิ่งเขียน (ขั้นตอนที่ 1.7) ฟังก์ชันนี้ใช้พารามิเตอร์ 2 รายการ ได้แก่ รหัสช่องและชื่อช่อง คุณต้องค้นหารหัสช่องและชื่อช่องจากทรัพยากรสตริงที่มีอยู่ในโปรเจ็กต์อยู่แล้ว
// EggTimerFragment.kt
    // TODO: Step 1.7 call createChannel
    createChannel(
          getString(R.string.egg_notification_channel_id),
          getString(R.string.egg_notification_channel_name)
    )
  1. คุณต้องส่งรหัสช่องไปยังเครื่องมือสร้างการแจ้งเตือน คุณได้ทำขั้นตอนนี้แล้วในขั้นตอนที่ 1.2 การตั้งค่าที่ไม่ถูกต้องเป็นรหัสช่องจะทำให้การแจ้งเตือนล้มเหลว เปิด NotificationUtils.kt เพื่อยืนยันว่ารหัสช่องที่คุณตั้งค่าไว้ก่อนหน้านี้ถูกต้อง
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
        applicationContext,
       // TODO: Step 1.8 verify the notification channel name
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. เรียกใช้แอป แล้วคุณจะเห็นว่าแอปส่งการแจ้งเตือนทุกครั้งที่คุณเริ่มตัวจับเวลา
  2. ดึงแถบสถานะลงแล้วสังเกตว่าชื่อ เนื้อหา และไอคอนของการแจ้งเตือนเป็นไปตามที่คุณตั้งค่าไว้ในขั้นตอนก่อนหน้า
  3. หากต้องการยืนยันช่องที่สร้างใหม่ ให้ปิดแอปแล้วมองหาไอคอนแอป แตะไอคอนแอปค้างไว้ แล้วเลือกข้อมูลแอป

  1. เลือกการแจ้งเตือนจากรายการการตั้งค่า คุณควรเห็นช่องใหม่ชื่อ Egg อยู่ใต้การตั้งค่าแสดงการแจ้งเตือน

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

ขั้นตอนที่ 3: เพิ่มการแจ้งเตือนลงในแอป

ตอนนี้เราได้เห็นการใช้งานพื้นฐานของ Notifications API แล้ว แต่การส่งการแจ้งเตือนทันทีหลังจากเริ่มตัวจับเวลาอาจไม่สมเหตุสมผลนัก ผู้ใช้น่าจะต้องการรับการแจ้งเตือนเมื่อไข่พร้อมฟัก ในส่วนถัดไปของโค้ดแล็บ คุณจะแก้ไขปัญหานี้และเปลี่ยนข้อความ Toast เป็นการแจ้งเตือน

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

แอปของคุณใช้ AlarmManager เพื่อตั้งปลุก โค้ดที่เกี่ยวข้องกับ AlarmManager มีอยู่ในโค้ดเริ่มต้นแล้วและใช้เพื่อแสดงข้อความ Toast AlarmManager จะติดตามการเลือกเวลาที่ต้องการและจะเรียกใช้ฟังก์ชัน onReceive() ของ AlarmReceiver.kt เมื่อถึงเวลา หากเปิด AlarmReceiver.kt แล้วไปที่ onReceive() คุณจะเห็นข้อความป๊อปอัปที่แสดงทุกครั้งที่ตั้งเวลานับไข่

  1. เปิด AlarmReceiver.kt ซึ่งเป็นอินสแตนซ์ของ NotificationManager แล้วเรียกใช้ฟังก์ชัน sendNotification() ด้วยข้อความและพารามิเตอร์บริบท
// AlarmReceiver.kt
   // TODO: Step 1.9 add call to sendNotification
   val notificationManager = ContextCompat.getSystemService(
       context, 
       NotificationManager::class.java
   ) as NotificationManager
             
   notificationManager.sendNotification(
       context.getText(R.string.eggs_ready).toString(), 
       context
   )
  1. คุณอาจนำข้อความป๊อปอัปออกได้เนื่องจากแอปจะส่งการแจ้งเตือนเมื่อตัวจับเวลาหมด
// AlarmReceiver.kt
     // TODO: Step 1.10 [Optional] remove toast
//   Toast.makeText(
//       context, 
//       context.getText(R.string.eggs_ready),
//       Toast.LENGTH_SHORT
//   ).show()
  1. เรียกใช้แอป คุณควรเห็นการแจ้งเตือนทุกครั้งที่เริ่มตัวจับเวลาและทุกครั้งที่ตัวจับเวลาหมด

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

  1. เปิด EggTimerFragment.kt แล้วนำรหัสการแจ้งเตือนสำหรับขั้นตอนที่ 1.5 ออก
// EggTimeViewModel.kt

// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
//      app,
//      NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
  1. เรียกใช้แอปอีกครั้ง
  2. ตั้งตัวจับเวลา แล้ววางไว้ที่พื้นหลังและรอจนกว่าจะหมดเวลา คุณจะเห็นการแจ้งเตือน ซึ่งเป็นการแจ้งเตือนที่มีประโยชน์มากกว่า

ขั้นตอนที่ 4: เพิ่มความตั้งใจในการค้นหาเนื้อหา

  1. เรียกใช้แอปอีกครั้งหากยังไม่ได้เรียกใช้
  2. คลิกการแจ้งเตือน ไม่มีอะไรเกิดขึ้น

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

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

  1. เปิด NotificationUtils.kt แล้วค้นหาฟังก์ชันส่วนขยาย sendNotification()
  2. สร้าง Intent ด้วย applicationContext และกิจกรรมที่จะเปิดใช้ MainActivity::class.java
// NotificationUtils.kt

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
    // Create the content intent for the notification, which launches
    // this activity
   // TODO: Step 1.11 create intent
    val contentIntent = Intent(applicationContext, MainActivity::class.java)

คุณสร้าง Intent แล้ว แต่การแจ้งเตือนแสดงนอกแอป หากต้องการให้ Intent ทำงานนอกแอป คุณต้องสร้าง PendingIntent ใหม่

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

  1. สร้าง PendingIntent ด้วย applicationContext, NOTIFICATION_ID, contentIntent ที่คุณสร้างในขั้นตอนก่อนหน้า และธง PendingIntent แฟล็ก PendingIntent ระบุตัวเลือกในการสร้าง PendingIntent ใหม่หรือใช้ที่มีอยู่ คุณต้องตั้งค่า PendingIntent.FLAG_UPDATE_CURRENT เป็นแฟล็กเนื่องจากคุณไม่ต้องการสร้างการแจ้งเตือนใหม่หากมีการแจ้งเตือนอยู่แล้ว วิธีนี้จะช่วยให้คุณแก้ไข PendingIntent ปัจจุบันซึ่งเชื่อมโยงกับเจตนาที่คุณระบุ
// NotificationUtils.kt
   // TODO: Step 1.12 create PendingIntent
    val contentPendingIntent = PendingIntent.getActivity(
        applicationContext, 
        NOTIFICATION_ID,
        contentIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
    )
  1. ส่ง PendingIntent ไปยังการแจ้งเตือน โดยโทรหา setContentIntent() ที่ NotificationBuilder ตอนนี้เมื่อคุณคลิกการแจ้งเตือน ระบบจะทริกเกอร์ PendingIntent เพื่อเปิด MainActivity
  2. และตั้งค่า setAutoCancel() เป็น true เพื่อให้เมื่อผู้ใช้แตะการแจ้งเตือน การแจ้งเตือนจะปิดตัวเองเมื่อนำผู้ใช้ไปยังแอป
// NotificationUtils.kt
    // TODO: Step 1.13 set content intent
    .setContentIntent(contentPendingIntent)
    .setAutoCancel(true)
  1. เรียกใช้แอปอีกครั้ง
  2. ตั้งค่าตัวจับเวลา ใส่แอปไว้ในเบื้องหลัง แล้วรอให้การแจ้งเตือนปรากฏขึ้น
  3. เมื่อเห็นการแจ้งเตือนแล้ว ให้คลิกการแจ้งเตือนโดยดึงแถบสถานะลงมา แล้วสังเกตว่าแอปจะเข้าสู่เบื้องหน้าได้อย่างไร

ขั้นตอนที่ 5: ยกเลิกการแจ้งเตือน

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

หากต้องการแก้ไขปัญหานี้ คุณต้องล้างการแจ้งเตือนก่อนหน้าเมื่อเริ่มตั้งเวลานับถอยหลังใหม่ เริ่มต้นด้วยการสร้างฟังก์ชันส่วนขยายอีกฟังก์ชันหนึ่งใน NotificationUtils.kt NotificationManager มี API สำหรับยกเลิกการแจ้งเตือนที่ใช้งานอยู่ทั้งหมดชื่อ cancelAll()

  1. เปิด NotificationsUtil.kt
  2. เพิ่มฟังก์ชันส่วนขยายใน NotificationManager ซึ่งเรียกใช้ cancelAll()
// NotificationUtils.kt

// TODO: Step 1.14 Cancel all notifications
/**
 * Cancels all notifications.
 *
 */
fun NotificationManager.cancelNotifications() {
    cancelAll()
}
  1. เปิด EggTimerViewModel.kt แล้วไปที่ฟังก์ชัน startTimer()
  2. ภายใน startTimer() ให้รับอินสแตนซ์ของ NotificationManager จากระบบและเรียกใช้ cancelNotifications()
//  EggTimerViewModel.kt
   //TODO Step 1.15 call cancel notification
    val notificationManager =
       ContextCompat.getSystemService(
            app,
            NotificationManager::class.java
        ) as NotificationManager
    notificationManager.cancelNotifications()       
  1. เรียกใช้แอปและเริ่มจับเวลา
  2. หลังจากเห็นการแจ้งเตือน ให้เริ่มตัวจับเวลาอีกครั้งและสังเกตว่าแอปของเราจะลบการแจ้งเตือนก่อนหน้าออกจากแถบสถานะโดยอัตโนมัติอย่างไร

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

ขั้นตอนที่ 1: จัดรูปแบบการแจ้งเตือน

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

NotificationCompat มีสไตล์ในตัวสำหรับ

  • BigTextStyle ซึ่งแสดงข้อความจำนวนมากได้ เช่น แสดงเนื้อหาของอีเมลเมื่อขยาย
  • BigPictureStyle ซึ่งแสดงการแจ้งเตือนรูปแบบขนาดใหญ่ที่มีไฟล์แนบเป็นรูปภาพขนาดใหญ่
  • InboxStyle ซึ่งแสดงเนื้อหาข้อความในรูปแบบการสนทนา
  • MediaStyle ซึ่งจะแสดงตัวควบคุมการเล่นสื่อ
  • MessagingStyle ซึ่งจะแสดงการแจ้งเตือนรูปแบบขนาดใหญ่ที่มีข้อความหลายรายการระหว่างผู้ใช้จำนวนเท่าใดก็ได้

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

  1. เปิด NotificationUtils.kt แล้วค้นหาฟังก์ชัน sendNotification()
  2. เริ่มต้นด้วยการโหลดรูปภาพจาก resources โดยใช้ BitmapFactory
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
  1. สร้าง BigPictureStyle ใหม่และตั้งค่ารูปภาพ
  2. ตั้งค่า bigLargeIcon() เป็น null เพื่อให้ไอคอนขนาดใหญ่หายไปเมื่อขยายการแจ้งเตือน
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
        .bigPicture(eggImage)
        .bigLargeIcon(null)
  1. ตั้งค่ารูปแบบด้วย setStyle() เป็น bigPicStyle
  2. ตั้งค่าไอคอนขนาดใหญ่ด้วย setLargeIcon() เป็น eggImage เพื่อให้รูปภาพแสดงเป็นไอคอนขนาดเล็กเมื่อการแจ้งเตือนยุบ
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
  1. เรียกใช้แอปและตั้งตัวจับเวลา เมื่อการแจ้งเตือนแสดงเป็นครั้งแรก การแจ้งเตือนจะอยู่ในสถานะยุบในลิ้นชักการแจ้งเตือน หากขยายการแจ้งเตือน ระบบจะแสดงรูปภาพขนาดใหญ่ในพื้นที่การแจ้งเตือนที่ขยาย

ขั้นตอนที่ 2: การดำเนินการกับการแจ้งเตือน

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

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

หากต้องการเพิ่มปุ่มการดำเนินการ ให้ส่ง PendingIntent ไปยังฟังก์ชัน addAction() ในเครื่องมือสร้าง ซึ่งคล้ายกับการตั้งค่าการแตะเริ่มต้นของการแจ้งเตือนโดยการเรียก setContentIntent() แต่คุณสามารถทำสิ่งอื่นๆ ได้หลากหลายแทนที่จะเปิดกิจกรรม เช่น เริ่ม BroadcastReceiver ที่ทำงานในเบื้องหลังเพื่อให้การดำเนินการไม่ขัดจังหวะแอปที่เปิดอยู่แล้ว

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

  1. เปิด SnoozeReceiver.kt ชั้นเรียนนี้คล้ายกับ AlarmReceiver ที่คุณเคยใช้ ในขั้นตอนต่อไปนี้ คุณจะเพิ่มโค้ดที่จะทริกเกอร์onReceive()ฟังก์ชันของSnoozeReceiver กล่าวโดยย่อคือ โค้ดใน SnoozeReceiver จะสร้างการปลุกใหม่เพื่อส่งการแจ้งเตือนใหม่ในอีก 1 นาทีต่อมา เลื่อนลงไปที่ด้านล่างของฟังก์ชัน onReceive รับอินสแตนซ์ของ notificationManager จากระบบ แล้วเรียกใช้ cancelAll
// SnoozeReceiver.kt
        val notificationManager = ContextCompat.getSystemService(
            context,
            NotificationManager::class.java
        ) as NotificationManager
        notificationManager.cancelAll()
  1. หากต้องการใช้ SnoozeReceiver ให้เปิด NotificationUtils.kt
  2. สร้าง Intent snoozeIntent ใหม่สำหรับ SnoozeReceiver ทันทีหลังจากสไตล์ในฟังก์ชัน sendNotification()
  3. สร้าง PendingIntent โดยเรียกใช้เมธอด getBroadcast() ใน PendingIntent ซึ่งคาดหวังพารามิเตอร์ในขั้นตอนต่อไปนี้ ระบบจะใช้ PendingIntent นี้เพื่อตั้งปลุกใหม่เพื่อโพสต์การแจ้งเตือนใหม่หลังจากผ่านไป 60 วินาทีเมื่อผู้ใช้แตะปุ่มเลื่อนการปลุก
  4. พารามิเตอร์แรกคือบริบทของแอปพลิเคชันที่ PendingIntent ควรเริ่มกิจกรรม
  5. พารามิเตอร์ที่ 2 คือรหัสคำขอ ซึ่งเป็นรหัสคำขอสำหรับ PendingIntent นี้ หากต้องการอัปเดตหรือยกเลิก Intent ที่รอดำเนินการนี้ คุณต้องใช้รหัสนี้เพื่อเข้าถึง Intent ที่รอดำเนินการ
  6. จากนั้นเพิ่มออบเจ็กต์ snoozeIntent ซึ่งเป็น Intent ของกิจกรรมที่จะเปิดตัว
  7. สุดท้าย ให้เพิ่มค่าแฟล็กของ #FLAG_ONE_SHOT เนื่องจากระบบจะใช้อินเทนต์เพียงครั้งเดียว การดำเนินการด่วนและการแจ้งเตือนจะหายไปหลังจากแตะครั้งแรก จึงใช้เจตนาได้เพียงครั้งเดียว
// NotificationUtils.kt

// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
    applicationContext, 
    REQUEST_CODE, 
    snoozeIntent, 
    FLAGS
)
  1. จากนั้นเรียกใช้ฟังก์ชัน addAction() ใน notificationBuilder ฟังก์ชันนี้ต้องการไอคอนและข้อความเพื่ออธิบายการดำเนินการของคุณต่อผู้ใช้ นอกจากนี้ คุณยังต้องเพิ่มsnoozeIntentด้วย ระบบจะใช้ความตั้งใจนี้เพื่อทริกเกอร์ boadcastReceiver ที่ถูกต้องเมื่อมีการคลิกการกระทำของคุณ
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
    R.drawable.egg_icon, 
    applicationContext.getString(R.string.snooze),
    snoozePendingIntent
)
  1. เรียกใช้แอปนาฬิกาทรายเพื่อทดสอบการเลื่อนการปลุก
  2. ตั้งเวลานับถอยหลังและวางแอปไว้เบื้องหลัง เมื่อตัวจับเวลาหมด ให้ขยายการแจ้งเตือน แล้วคุณจะเห็นว่าตอนนี้การแจ้งเตือนมีปุ่มการทำงานเลื่อนการแจ้งเตือน ซึ่งจะเลื่อนการแจ้งเตือนตัวจับเวลาไข่ไปอีก 1 นาที

ขั้นตอนที่ 3: ความสำคัญของการแจ้งเตือน

ความสำคัญจะกำหนดว่าการแจ้งเตือนควรรบกวนผู้ใช้ด้วยภาพและเสียงมากน้อยเพียงใด การแจ้งเตือนที่มีความสำคัญสูงจะรบกวนผู้ใช้มากขึ้น

คุณต้องระบุระดับความสำคัญในเครื่องมือสร้าง NotificationChannel คุณตั้งค่าความสำคัญของแอปจับเวลาไข่ไว้ต่ำตั้งแต่แรก คุณสามารถใช้ระดับความสำคัญ 1 ใน 5 ระดับได้ โดยมีตั้งแต่ IMPORTANCE_NONE(0) ถึง IMPORTANCE_HIGH(4) ระดับความสำคัญที่คุณกำหนดให้กับช่องจะมีผลกับข้อความแจ้งเตือนทั้งหมดที่คุณโพสต์ในช่องนั้น

ระดับความสำคัญของช่อง

ระดับความสำคัญที่ผู้ใช้มองเห็น

ความสำคัญ (Android 8.0 ขึ้นไป)

ลำดับความสำคัญ (Android 7.1 และต่ำกว่า)

มีเสียงเตือนและแสดงเป็นการแจ้งเตือนล่วงหน้า (ปรากฏที่ด้านบนของหน้าจอ)

IMPORTANCE_HIGH

PRIORITY_HIGH / PRIORITY_MAX

ส่งเสียง

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

ไม่มีเสียง

IMPORTANCE_LOW

PRIORITY_LOW

ไม่มีเสียงเตือนและไม่ปรากฏในแถบสถานะ

IMPORTANCE_MIN

PRIORITY_MIN

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

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

  1. หากต้องการเปลี่ยนระดับความสำคัญของช่องการแจ้งเตือนของแอป ให้เปิด EggTimerFragment.kt แล้วไปที่ createChannel() เปลี่ยนระดับความสำคัญจาก IMPORTANCE_LOW เป็น IMPORTANCE_HIGH
// EggTimerFragment.kt
    val notificationChannel = NotificationChannel(
        channelId,
        channelName,
        // TODO: Step 2.4 change importance
        NotificationManager.IMPORTANCE_HIGH
    )

หากต้องการรองรับอุปกรณ์ที่ใช้ Android 7.1 (API ระดับ 25) หรือต่ำกว่า คุณต้องเรียกใช้ setPriority() สำหรับการแจ้งเตือนแต่ละรายการด้วย โดยใช้ค่าคงที่ลำดับความสำคัญจากคลาส NotificationCompat

  1. เปิด NotificationUtils.kt แล้วเพิ่มรายการต่อไปนี้ลงในออบเจ็กต์เครื่องมือสร้างการแจ้งเตือน
// NotificationUtils.kt
   .addAction(
       R.drawable.common_google_signin_btn_icon_dark,
       applicationContext.getString(R.string.snooze),
       snoozePendingIntent
    )
   // TODO: Step 2.5 set priority
    .setPriority(NotificationCompat.PRIORITY_HIGH)
  1. ก่อนเรียกใช้แอป ให้คลิกไอคอนแอปในอุปกรณ์หรือโปรแกรมจำลองค้างไว้ แล้วเลือกถอนการติดตั้งเพื่อล้างการตั้งค่าช่องก่อนหน้า หากถอนการติดตั้งแอปไม่สำเร็จ การตั้งค่าลำดับความสำคัญของช่องจะไม่เปลี่ยนแปลง และจะไม่มีการเปลี่ยนแปลงลักษณะการทำงานเมื่อมีการโพสต์การแจ้งเตือน
  2. ตอนนี้ให้เรียกใช้แอปอีกครั้งแล้วเริ่มจับเวลา คราวนี้เมื่อมีการนำส่งการแจ้งเตือน คุณควรเห็นป๊อปอัปปรากฏที่ด้านบนของหน้าจอ ไม่ว่าแอปจะทำงานในเบื้องหน้าหรือเบื้องหลังก็ตาม

ขั้นตอนที่ 4: ป้ายการแจ้งเตือน

ป้ายการแจ้งเตือนคือจุดเล็กๆ ที่ปรากฏบนไอคอน Launcher ของแอปที่เชื่อมโยงเมื่อแอปมีการแจ้งเตือนที่ใช้งานอยู่ ผู้ใช้กดไอคอนแอปค้างไว้เพื่อดูการแจ้งเตือนได้

จุดเหล่านี้เรียกว่าป้าย ซึ่งจะปรากฏโดยค่าเริ่มต้นและแอปของคุณไม่จำเป็นต้องดำเนินการใดๆ อย่างไรก็ตาม อาจมีบางกรณีที่ป้ายไม่เหมาะกับการแจ้งเตือนของคุณ ดังนั้นคุณจึงปิดใช้ป้ายได้ทีละช่องโดยเรียกใช้ setShowBadge(false) ในออบเจ็กต์ NotificationChannel เนื่องจากตัวจับเวลาไข่มีการแจ้งเตือนที่ใช้งานอยู่เพียงรายการเดียวในเวลาที่กำหนด ป้ายบนไอคอนแอปจึงไม่ได้มีประโยชน์มากนักสำหรับผู้ใช้ ในขั้นตอนต่อไปนี้ คุณจะปิดใช้ป้ายและแสดงการแจ้งเตือนสำหรับตัวจับเวลาไข่เท่านั้น

  1. เพิ่ม setShowBadge(false) ลงในโค้ดการสร้างแชแนลสำหรับนาฬิกาจับเวลาไข่เพื่อปิดใช้ป้าย
// EggTimerFragment.kt

    ).apply {
        // TODO: Step 2.6 disable badges for this channel
        setShowBadge(false)
    }
  1. เรียกใช้แอปอีกครั้ง เริ่มตัวจับเวลา แล้วดูไอคอนแอป คุณไม่ควรเห็นป้ายใดๆ บนไอคอนแอป

โค้ดโซลูชันอยู่ในสาขาหลักของโค้ดที่คุณดาวน์โหลด

  • ใช้คลาส NotificationManager เพื่อสร้าง ส่ง อัปเดต และยกเลิกการแจ้งเตือน
  • ใช้ออบเจ็กต์ NotificationChannel กับเมธอด createNotificationChannel เพื่อตั้งค่าแชแนลสำหรับการแจ้งเตือน
  • ใช้ addAction() เพื่อเพิ่มการดำเนินการด่วนในการแจ้งเตือน
  • ใช้ setShowBadge() เพื่อเปิดหรือปิดใช้ป้าย
  • จัดรูปแบบการแจ้งเตือนโดยใช้สไตล์ที่ขยายจาก Notification.Style
  • ตั้งค่าระดับความสำคัญด้วย NotificationChannel.setImportance()

หลักสูตร Udacity:

เอกสารประกอบสำหรับนักพัฒนาแอป Android

ดูลิงก์ไปยัง Codelab อื่นๆ ในหลักสูตรนี้ได้ที่หน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin