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

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

โค้ดในหน้านี้ใช้เมธอด NotificationCompat API จากไลบรารี AndroidX API เหล่านี้ให้คุณเพิ่มฟีเจอร์ที่มีเฉพาะ ใน Android เวอร์ชันใหม่ และในขณะเดียวกันก็ยังให้ ความสามารถในการใช้งานร่วมกันกับ Android 9 (API ระดับ 28) แต่บางฟีเจอร์ เช่น การตอบกลับแบบแทรกในบรรทัด จะทำให้ไม่มีการดำเนินการในเวอร์ชันก่อนหน้า

เพิ่มไลบรารี AndroidX Core

แม้ว่าโปรเจ็กต์ส่วนใหญ่ที่สร้างด้วย Android Studio จะมี ทรัพยากร Dependency ที่จะใช้ NotificationCompat โปรดยืนยันว่าระดับโมดูลของคุณ ไฟล์ build.gradle มีทรัพยากร Dependency ต่อไปนี้

ดึงดูด

dependencies {
    implementation "androidx.core:core:2.2.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-ktx:2.2.0")
}

สร้างการแจ้งเตือนพื้นฐาน

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

รูปที่ 1 การแจ้งเตือนที่มี ไอคอน ชื่อ และข้อความบางอย่าง

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการแจ้งเตือนแต่ละส่วน โปรดอ่านเกี่ยวกับการแจ้งเตือน กายวิภาคศาสตร์

ประกาศสิทธิ์รันไทม์

Android 13 (API ระดับ 33) ขึ้นไปรองรับสิทธิ์รันไทม์สำหรับการโพสต์ การแจ้งเตือนที่ไม่ได้ยกเว้น (รวมถึงบริการที่ทำงานอยู่เบื้องหน้า (FGS)) จากแอป

สิทธิ์ที่คุณต้องประกาศในไฟล์ Manifest ของแอปจะปรากฏขึ้น ในข้อมูลโค้ดต่อไปนี้

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

ดูรายละเอียดเพิ่มเติมเกี่ยวกับสิทธิ์รันไทม์ได้ที่ สิทธิ์รันไทม์ของการแจ้งเตือน

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

ในการเริ่มต้นใช้งาน ให้ตั้งค่าเนื้อหาและช่องของการแจ้งเตือนโดยใช้ NotificationCompat.Builder ออบเจ็กต์ ตัวอย่างต่อไปนี้จะแสดงวิธีสร้างการแจ้งเตือนด้วย ดังต่อไปนี้:

  • ไอคอนขนาดเล็ก ตั้งค่าโดย setSmallIcon() ซึ่งเป็นเนื้อหาเดียวที่จำเป็นต่อผู้ใช้

  • ชื่อ ตั้งค่าโดย setContentTitle()

  • ข้อความส่วนเนื้อหา ตั้งค่าโดย setContentText()

  • ลำดับความสำคัญของการแจ้งเตือนซึ่งกำหนดโดย setPriority() ลำดับความสำคัญเป็นตัวกำหนดว่าการแจ้งเตือนรบกวนผู้ใช้บน Android 7.1 มากน้อยเพียงใด และ ก่อนหน้านี้ สำหรับ Android 8.0 ขึ้นไป ให้ตั้งค่าความสำคัญของช่องเป็น จะแสดงในส่วนถัดไป

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

ตัวสร้าง NotificationCompat.Builder ต้องการให้คุณระบุช่อง ID ซึ่งจำเป็นสำหรับความเข้ากันได้กับ Android 8.0 (API ระดับ 26) และ แต่จะถูกละเว้นโดยเวอร์ชันก่อนหน้า

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

รูปที่ 2 โฆษณาแบบขยายได้ ในแบบฟอร์มที่ยุบและขยาย

หากคุณต้องการขยายการแจ้งเตือนให้ยาวขึ้น คุณสามารถเปิดใช้โฆษณาแบบขยายได้ โดยเพิ่มเทมเพลตรูปแบบด้วย setStyle() ตัวอย่างเช่น โค้ดต่อไปนี้สร้างพื้นที่ข้อความขนาดใหญ่ขึ้น

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

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

สร้างช่องและกำหนดความสำคัญ

ก่อนที่คุณจะสามารถส่งการแจ้งเตือนบน Android 8.0 ขึ้นไป ให้ลงทะเบียน ช่องทางการแจ้งเตือนของแอป ด้วยการส่งข้อมูลอินสแตนซ์ NotificationChannel ถึง createNotificationChannel() โค้ดต่อไปนี้ถูกบล็อกโดยเงื่อนไขใน เวอร์ชัน SDK_INT:

Kotlin

private fun createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system.
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

Java

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this.
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

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

ตัวสร้าง NotificationChannel ต้องการ importance โดยใช้หนึ่งใน ค่าคงที่จาก NotificationManager ชั้นเรียน ช่วงเวลานี้ กำหนดวิธีรบกวนผู้ใช้สำหรับการแจ้งเตือนที่มี มาที่ช่องนี้ ตั้งค่าลำดับความสำคัญด้วย setPriority() เพื่อรองรับ Android 7.1 และก่อนหน้านี้ ดังที่แสดงในตัวอย่างก่อนหน้านี้

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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความหมายของระดับต่างๆ โปรดอ่านเกี่ยวกับ ความสำคัญของการแจ้งเตือน ระดับต่างๆ

ตั้งค่าการดำเนินการแตะของการแจ้งเตือน

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

ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้าง Intent พื้นฐานเพื่อเปิดกิจกรรม เมื่อผู้ใช้แตะการแจ้งเตือน

Kotlin

// Create an explicit intent for an Activity in your app.
val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)

Java

// Create an explicit intent for an Activity in your app.
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

โค้ดนี้เรียกใช้ setAutoCancel() ซึ่งจะนำการแจ้งเตือนออกโดยอัตโนมัติเมื่อผู้ใช้แตะ

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

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

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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีต่างๆ ในการกำหนดค่า Intent ของการแจ้งเตือน โปรดดู เริ่มกิจกรรมจากการแจ้งเตือน

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

หากต้องการให้การแจ้งเตือนปรากฏขึ้น ให้โทร NotificationManagerCompat.notify() การส่งรหัสที่ไม่ซ้ำสำหรับการแจ้งเตือนและผลลัพธ์ของ NotificationCompat.Builder.build() ตัวอย่างนี้จะแสดงในตัวอย่างต่อไปนี้

Kotlin

with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        // ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,
        //                                        grantResults: IntArray)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        return@with
    }
    // notificationId is a unique int for each notification that you must define.
    notify(NOTIFICATION_ID, builder.build())
}

Java

with(NotificationManagerCompat.from(this)) {
   if (ActivityCompat.checkSelfPermission(
           this@MainActivity,
           Manifest.permission.POST_NOTIFICATIONS
       ) != PackageManager.PERMISSION_GRANTED
   ) {
       // TODO: Consider calling
       // ActivityCompat#requestPermissions
       // here to request the missing permissions, and then overriding
       // public void onRequestPermissionsResult(int requestCode, String[] permissions,
       //                                        int[] grantResults)
       // to handle the case where the user grants the permission. See the documentation
       // for ActivityCompat#requestPermissions for more details.

       return
   }
   // notificationId is a unique int for each notification that you must define.
   notify(NOTIFICATION_ID, builder.build())
}

บันทึกรหัสการแจ้งเตือนที่คุณส่งไปยัง NotificationManagerCompat.notify() เพราะคุณต้องใช้ข้อมูลนี้เมื่อต้องการอัปเดตหรือลบ การแจ้งเตือน

นอกจากนี้ เพื่อที่จะทดสอบการแจ้งเตือนพื้นฐานในอุปกรณ์ที่ทำงานบน Android 13 ขึ้นไป โปรดเปิดการแจ้งเตือนด้วยตนเองหรือสร้างกล่องโต้ตอบเพื่อ การแจ้งเตือนคำขอ

เพิ่มปุ่มการทำงาน

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

รูปที่ 3 การแจ้งเตือนที่มี ปุ่มการทำงานเดียว

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

ตัวอย่างเช่น โค้ดต่อไปนี้แสดงวิธีส่งการประกาศไปยัง ผู้รับ:

Kotlin

val ACTION_SNOOZE = "snooze"

val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
    action = ACTION_SNOOZE
    putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
    PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)</span>
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)

Java

String ACTION_SNOOZE = "snooze"

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);</span>

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้าง BroadcastReceiver เพื่อเรียกใช้พื้นหลัง โปรดดูภาพรวมการแพร่สัญญาณ

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

เพิ่มการตอบโดยตรง

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

รูปที่ 4 แตะ "ตอบกลับ" จะเปิดการป้อนข้อความ

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

เพิ่มปุ่มตอบ

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

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

    Kotlin

      // Key for the string that's delivered in the action's intent.
      private val KEY_TEXT_REPLY = "key_text_reply"
      var replyLabel: String = resources.getString(R.string.reply_label)
      var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run {
          setLabel(replyLabel)
          build()
      }
      

    Java

      // Key for the string that's delivered in the action's intent.
      private static final String KEY_TEXT_REPLY = "key_text_reply";
    
      String replyLabel = getResources().getString(R.string.reply_label);
      RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
              .setLabel(replyLabel)
              .build();
      
  2. สร้าง PendingIntent สำหรับการดำเนินการตอบกลับ

    Kotlin

      // Build a PendingIntent for the reply action to trigger.
      var replyPendingIntent: PendingIntent =
          PendingIntent.getBroadcast(applicationContext,
              conversation.getConversationId(),
              getMessageReplyIntent(conversation.getConversationId()),
              PendingIntent.FLAG_UPDATE_CURRENT)
      

    Java

      // Build a PendingIntent for the reply action to trigger.
      PendingIntent replyPendingIntent =
              PendingIntent.getBroadcast(getApplicationContext(),
                      conversation.getConversationId(),
                      getMessageReplyIntent(conversation.getConversationId()),
                      PendingIntent.FLAG_UPDATE_CURRENT);
      
  3. แนบไฟล์ RemoteInput ของการดำเนินการโดยใช้ addRemoteInput()

    Kotlin

      // Create the reply action and add the remote input.
      var action: NotificationCompat.Action =
          NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
              getString(R.string.label), replyPendingIntent)
              .addRemoteInput(remoteInput)
              .build()
      

    Java

      // Create the reply action and add the remote input.
      NotificationCompat.Action action =
              new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                      getString(R.string.label), replyPendingIntent)
                      .addRemoteInput(remoteInput)
                      .build();
      
  4. ดำเนินการกับการแจ้งเตือนและส่งการแจ้งเตือน

    Kotlin

      // Build the notification and add the action.
      val newMessageNotification = Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build()
    
      // Issue the notification.
      with(NotificationManagerCompat.from(this)) {
          notificationManager.notify(notificationId, newMessageNotification)
      }
      

    Java

      // Build the notification and add the action.
      Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build();
    
      // Issue the notification.
      NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
      notificationManager.notify(notificationId, newMessageNotification);
      

ระบบจะแจ้งให้ผู้ใช้ป้อนคำตอบเมื่อเรียกใช้ การดำเนินการแจ้งเตือนดังที่แสดงในรูปที่ 4

ดึงข้อมูลจากผู้ใช้จากการตอบกลับ

หากต้องการรับข้อมูลจากผู้ใช้จาก UI การตอบกลับการแจ้งเตือน ให้โทร RemoteInput.getResultsFromIntent() ส่งต่อ Intent ที่ BroadcastReceiver ของคุณได้รับ:

Kotlin

private fun getMessageText(intent: Intent): CharSequence? {
    return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
}

Java

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

หลังจากประมวลผลข้อความแล้ว ให้อัปเดตการแจ้งเตือนด้วยการโทร NotificationManagerCompat.notify() ที่มีรหัสและแท็กเดียวกัน หากใช้ นี่คือ เพื่อซ่อน UI การตอบกลับโดยตรง และยืนยันกับผู้ใช้ว่าการตอบกลับ ได้รับและประมวลผลอย่างถูกต้อง

Kotlin

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
val repliedNotification = Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build()

// Issue the new notification.
NotificationManagerCompat.from(this).apply {
    notificationManager.notify(notificationId, repliedNotification)
}

Java

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

เมื่อใช้งานการแจ้งเตือนใหม่นี้ ให้ใช้บริบทที่ส่งไปยัง ของผู้รับ onReceive()

เพิ่มการตอบกลับที่ด้านล่างของการแจ้งเตือนด้วยการโทร setRemoteInputHistory() แต่ถ้าคุณจะสร้างแอปรับส่งข้อความ ให้สร้างรูปแบบการรับส่งข้อความ และใส่เครื่องหมาย ข้อความใหม่ในการสนทนา

สำหรับคำแนะนำเพิ่มเติมเกี่ยวกับการแจ้งเตือนจากแอปรับส่งข้อความ โปรดดูส่วนเกี่ยวกับ แนวทางปฏิบัติแนะนำสำหรับแอปรับส่งข้อความ

เพิ่มแถบความคืบหน้า

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

รูปที่ 5 แถบความคืบหน้าระหว่าง การดำเนินการ

หากคุณสามารถคาดคะเนได้ว่าการดำเนินการเสร็จสมบูรณ์มากน้อยเพียงใดเมื่อใดก็ตาม ให้ใช้ "กำหนด" ของตัวบ่งชี้ตามที่แสดงในรูปที่ 5 โดยการเรียก setProgress(max, progress, false) พารามิเตอร์แรกคือพารามิเตอร์ "complete" เช่น 100 รายการที่ 2 คือ เสร็จสมบูรณ์แล้ว สถานะสุดท้ายระบุว่านี่เป็นความคืบหน้าที่แน่วแน่ แถบ

ขณะดำเนินการ ให้เรียกใช้ setProgress(max, progress, false) อย่างต่อเนื่องด้วยค่า progress ที่อัปเดต และออกการแจ้งเตือนอีกครั้งตาม ที่แสดงในตัวอย่างต่อไปนี้

Kotlin

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentTitle("Picture Download")
    setContentText("Download in progress")
    setSmallIcon(R.drawable.ic_notification)
    setPriority(NotificationCompat.PRIORITY_LOW)
}
val PROGRESS_MAX = 100
val PROGRESS_CURRENT = 0
NotificationManagerCompat.from(this).apply {
    // Issue the initial notification with zero progress.
    builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false)
    notify(notificationId, builder.build())

    // Do the job that tracks the progress here.
    // Usually, this is in a worker thread.
    // To show progress, update PROGRESS_CURRENT and update the notification with:
    // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    // notificationManager.notify(notificationId, builder.build());

    // When done, update the notification once more to remove the progress bar.
    builder.setContentText("Download complete")
            .setProgress(0, 0, false)
    notify(notificationId, builder.build())
}

Java

...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification)
        .setPriority(NotificationCompat.PRIORITY_LOW);

// Issue the initial notification with zero progress.
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(notificationId, builder.build());

// Do the job that tracks the progress here.
// Usually, this is in a worker thread.
// To show progress, update PROGRESS_CURRENT and update the notification with:
// builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
// notificationManager.notify(notificationId, builder.build());

// When done, update the notification once more to remove the progress bar.
builder.setContentText("Download complete")
        .setProgress(0,0,false);
notificationManager.notify(notificationId, builder.build());

เมื่อสิ้นสุดการดำเนินการ progress ต้องเท่ากับ max คุณสามารถออกจาก แถบความคืบหน้าเพื่อแสดงว่าการดำเนินการเสร็จสิ้นแล้วหรือนำออก ไม่ว่าในกรณีใด อัปเดตข้อความแจ้งเตือนเพื่อแสดงว่าการดำเนินการเสร็จสิ้นแล้ว วิธีนำออก แถบความคืบหน้า โทรหา setProgress(0, 0, false)

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

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

ตั้งค่าหมวดหมู่สำหรับทั้งระบบ

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

หากการแจ้งเตือนของคุณอยู่ในหมวดหมู่การแจ้งเตือนใดหมวดหมู่หนึ่งที่กำหนดไว้ใน NotificationCompat เช่น CATEGORY_ALARM, CATEGORY_REMINDER, CATEGORY_EVENT หรือ CATEGORY_CALL - ประกาศ โดยการส่งหมวดหมู่ที่เหมาะสมไปยัง setCategory():

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE);

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

แสดงข้อความด่วน

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

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

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

ข้อมูลโค้ดต่อไปนี้แสดงวิธีเชื่อมโยงการแจ้งเตือนกับ Intent แบบเต็มหน้าจอ

Kotlin

val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true)

Java

Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true);

ตั้งค่าระดับการเข้าถึงหน้าจอล็อก

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

  • VISIBILITY_PUBLIC: เนื้อหาทั้งหมดของการแจ้งเตือนจะแสดงบนหน้าจอล็อก

  • VISIBILITY_SECRET: จะไม่มีส่วนใดของการแจ้งเตือนแสดงบนหน้าจอล็อก

  • VISIBILITY_PRIVATE: เฉพาะข้อมูลพื้นฐาน เช่น ไอคอนของการแจ้งเตือนและเนื้อหา ชื่อ แสดงอยู่ บนหน้าจอล็อก เนื้อหาทั้งหมดของการแจ้งเตือนไม่ โชว์

เมื่อตั้งค่า VISIBILITY_PRIVATE คุณยังระบุเวอร์ชันสำรองของ เนื้อหาการแจ้งเตือนที่ซ่อนรายละเอียดบางอย่าง เช่น แอป SMS อาจแสดงการแจ้งเตือนที่แสดงว่า "คุณมีข้อความใหม่ 3 ข้อความ" แต่ ซ่อนเนื้อหาข้อความและผู้ส่ง เพื่อให้ทางเลือกนี้ การแจ้งเตือน ให้สร้างการแจ้งเตือนอื่นก่อน NotificationCompat.Builderตามปกติ จากนั้น แนบการแจ้งเตือนอื่น ไปยังการแจ้งเตือนปกติที่มี setPublicVersion()

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

อัปเดตการแจ้งเตือน

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

คุณสามารถเลือกโทร setOnlyAlertOnce() ดังนั้นการแจ้งเตือนของคุณจะรบกวนผู้ใช้ด้วยเสียง การสั่น หรือภาพ ข้อมูล เฉพาะครั้งแรกที่การแจ้งเตือนปรากฏขึ้น แต่ไม่จะแสดงในภายหลัง อัปเดต

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

การแจ้งเตือนจะยังคงแสดงอยู่จนกว่าจะเกิดเหตุการณ์ใดกรณีหนึ่งต่อไปนี้

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

แนวทางปฏิบัติแนะนำสำหรับแอปรับส่งข้อความ

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

ใช้ MessagingStyle

เริ่มตั้งแต่ Android 7.0 (API ระดับ 24) เป็นต้นไป Android จะมีรูปแบบการแจ้งเตือน เทมเพลตสำหรับเนื้อหาการรับส่งข้อความโดยเฉพาะ การใช้ NotificationCompat.MessagingStyle คุณสามารถเปลี่ยนป้ายกำกับ ต่างๆ ที่แสดงในการแจ้งเตือนได้ ซึ่งรวมถึงชื่อการสนทนา ข้อความเพิ่มเติม และมุมมองเนื้อหาสำหรับ การแจ้งเตือนนั้น

ข้อมูลโค้ดต่อไปนี้แสดงวิธีปรับแต่งรูปแบบการแจ้งเตือน โดยใช้ชั้นเรียน MessagingStyle

Kotlin

val user = Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build()

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with $sender")
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build()

Java

Person user = new Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build();

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with " + sender)
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(new NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build();

ตั้งแต่ Android 9.0 (API ระดับ 28) เป็นต้นไป คุณยังต้องใช้เมธอด Person หากต้องการ การแสดงผลการแจ้งเตือนและรูปโปรไฟล์ที่เหมาะสมที่สุด

เมื่อใช้ NotificationCompat.MessagingStyle ให้ทำดังนี้

  • โทร MessagingStyle.setConversationTitle() เพื่อตั้งชื่อสำหรับแชทเป็นกลุ่มมากกว่า 2 คน ระดับพอดี ชื่อการสนทนาอาจเป็นชื่อของการแชทเป็นกลุ่มหรือหากไม่ มีชื่อ และมีรายชื่อผู้เข้าร่วมในการสนทนา ถ้าไม่มีสิ่งนี้ ข้อความอาจถูกเข้าใจผิดว่าเป็นการสนทนาแบบหนึ่งต่อหนึ่งกับ ผู้ส่งข้อความล่าสุดในการสนทนา
  • ใช้เมนู MessagingStyle.setData() ในการรวมข้อความสื่อ เช่น รูปภาพ ประเภท MIME ของรูปแบบ image/*

ใช้การตอบกลับโดยตรง

การตอบกลับโดยตรงช่วยให้ผู้ใช้ตอบกลับข้อความได้แบบแทรกในบรรทัด

  • หลังจากผู้ใช้ตอบกลับด้วยการตอบกลับแบบแทรกในบรรทัด ให้ใช้ MessagingStyle.addMessage() เพื่ออัปเดตการแจ้งเตือนของ MessagingStyle และอย่าเพิกถอนหรือยกเลิก การแจ้งเตือน การไม่ยกเลิกการแจ้งเตือนจะทำให้ผู้ใช้ส่งหลายรายการได้ การตอบกลับจากการแจ้งเตือน
  • หากต้องการให้การตอบกลับแบบแทรกในบรรทัดใช้ได้กับ Wear OS โปรดโทร Action.WearableExtender.setHintDisplayInlineAction(true)
  • ใช้เมนู addHistoricMessage() วิธีที่จะให้บริบทในการสนทนาตอบกลับโดยตรงโดยการเพิ่ม ไปยังการแจ้งเตือน

เปิดใช้ฟีเจอร์ช่วยตอบ

  • หากต้องการเปิดใช้สมาร์ทรีพลาย โปรดโทร setAllowGeneratedResponses(true) ในการดำเนินการตอบกลับ การดำเนินการนี้จะทำให้การตอบกลับจากฟีเจอร์ช่วยตอบพร้อมใช้งานกับ ผู้ใช้เมื่อมีการเชื่อมโยงการแจ้งเตือนกับอุปกรณ์ Wear OS ช่วยตอบ คำตอบจะสร้างขึ้นจากโมเดลแมชชีนเลิร์นนิงบนนาฬิกาทั้งหมดโดยใช้ บริบทจาก NotificationCompat.MessagingStyle และจะไม่มีการอัปโหลดข้อมูลไปยังอินเทอร์เน็ตเพื่อสร้าง คำตอบ

เพิ่มข้อมูลเมตาของการแจ้งเตือน

  • กำหนดข้อมูลเมตาการแจ้งเตือนเพื่อบอกระบบถึงวิธีจัดการแอปของคุณ การแจ้งเตือนเมื่ออุปกรณ์อยู่ใน Do Not Disturb mode ตัวอย่างเช่น ให้ใช้ addPerson() หรือ setCategory(Notification.CATEGORY_MESSAGE) ในการลบล้างโหมดห้ามรบกวน