Thông báo cung cấp thông tin ngắn gọn và kịp thời về các sự kiện trong ứng dụng khi ứng dụng không được sử dụng. Tài liệu này hướng dẫn bạn cách tạo một thông báo có nhiều tính năng. Để xem phần giới thiệu về cách thông báo xuất hiện trên Android, hãy xem bài viết Tổng quan về thông báo. Để xem mã mẫu sử dụng thông báo, hãy xem mẫu SociaLite trên GitHub.
Mã trên trang này sử dụng các API NotificationCompat
trong Thư viện AndroidX. Các API này cho phép bạn thêm những tính năng chỉ có trên các phiên bản Android mới hơn, đồng thời vẫn đảm bảo khả năng tương thích với Android 9 (API cấp 28). Tuy nhiên, một số tính năng, chẳng hạn như thao tác trả lời trực tiếp, sẽ không hoạt động trên các phiên bản cũ.
Thêm Thư viện AndroidX Core
Mặc dù hầu hết các dự án được tạo bằng Android Studio đều có các phần phụ thuộc cần thiết để sử dụng NotificationCompat
, nhưng hãy xác minh rằng tệp build.gradle
cấp mô-đun của bạn có phần phụ thuộc sau:
Groovy
dependencies { implementation "androidx.core:core-ktx:1.16.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.16.0") }
Tạo thông báo cơ bản
Thông báo ở dạng cơ bản và nhỏ gọn nhất (còn gọi là dạng thu gọn) sẽ hiển thị một biểu tượng, tiêu đề và một lượng nhỏ nội dung văn bản. Phần này cho biết cách tạo một thông báo mà người dùng có thể nhấn vào để chạy một hoạt động trong ứng dụng của bạn.
Hình 1. Một thông báo có biểu tượng, tiêu đề và một số văn bản.
Để biết thêm thông tin chi tiết về từng phần của thông báo, hãy đọc bài viết về cấu trúc thông báo.
Khai báo quyền khi bắt đầu chạy
Android 13 (API cấp 33) trở lên hỗ trợ quyền khi bắt đầu chạy để đăng thông báo không được miễn trừ (bao gồm cả Dịch vụ trên nền trước (FGS)) từ một ứng dụng.
Quyền mà bạn cần khai báo trong tệp kê khai của ứng dụng sẽ xuất hiện trong đoạn mã sau:
<manifest ...> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <application ...> ... </application> </manifest>
Để biết thêm thông tin chi tiết về quyền trong thời gian chạy, hãy xem phần Quyền trong thời gian chạy của thông báo.
Đặt nội dung thông báo
Để bắt đầu, hãy đặt nội dung và kênh của thông báo bằng cách sử dụng đối tượng NotificationCompat.Builder
. Ví dụ sau đây cho biết cách tạo thông báo có các thành phần sau:
Một biểu tượng nhỏ, do
setSmallIcon()
đặt. Đây là nội dung duy nhất mà người dùng thấy và bắt buộc phải có.Tiêu đề do
setContentTitle()
đặt.Nội dung, do
setContentText()
đặt.Mức độ ưu tiên của thông báo do
setPriority()
đặt. Mức độ ưu tiên xác định mức độ xâm nhập của thông báo trên Android 7.1 trở xuống. Đối với Android 8.0 trở lên, thay vào đó, hãy đặt mức độ quan trọng của kênh như minh hoạ trong phần tiếp theo.
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);
Hàm dựng NotificationCompat.Builder
yêu cầu bạn cung cấp mã nhận dạng kênh. Điều này là bắt buộc để tương thích với Android 8.0 (API cấp 26) trở lên, nhưng sẽ bị các phiên bản cũ hơn bỏ qua.
Theo mặc định, nội dung văn bản của thông báo sẽ bị cắt sao cho vừa đủ trong một dòng. Bạn có thể hiện thêm thông tin bằng cách tạo một thông báo có thể mở rộng.
Hình 2. Một thông báo có thể mở rộng ở dạng thu gọn và mở rộng.
Nếu muốn nội dung thông báo dài hơn, bạn có thể bật thông báo có thể mở rộng bằng cách thêm một mẫu kiểu có setStyle()
.
Ví dụ: mã sau đây tạo ra một vùng văn bản lớn hơn:
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);
Để biết thêm thông tin về các kiểu thông báo lớn khác, bao gồm cả cách thêm hình ảnh và các nút điều khiển chế độ phát nội dung nghe nhìn, hãy xem phần Tạo thông báo có thể mở rộng.
Tạo kênh và đặt mức độ quan trọng
Trước khi bạn có thể gửi thông báo trên Android 8.0 trở lên, hãy đăng ký kênh thông báo của ứng dụng với hệ thống bằng cách truyền một phiên bản của NotificationChannel
đến createNotificationChannel()
.
Đoạn mã sau đây bị chặn theo điều kiện trên phiên bản 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); } }
Vì bạn phải tạo kênh thông báo trước khi đăng bất kỳ thông báo nào trên Android 8.0 trở lên, hãy thực thi mã này ngay khi ứng dụng của bạn khởi động. Bạn có thể gọi phương thức này nhiều lần mà không gặp vấn đề gì, vì việc tạo một kênh thông báo hiện có sẽ không thực hiện thao tác nào.
Hàm dựng NotificationChannel
yêu cầu một importance
, sử dụng một trong các hằng số của lớp NotificationManager
. Tham số này xác định cách làm gián đoạn người dùng đối với mọi thông báo thuộc kênh này. Đặt priority bằng setPriority()
để hỗ trợ Android 7.1 trở xuống, như minh hoạ trong ví dụ trước.
Mặc dù bạn phải đặt mức độ quan trọng hoặc mức độ ưu tiên của thông báo như trong ví dụ sau, nhưng hệ thống không đảm bảo hành vi cảnh báo mà bạn nhận được. Trong một số trường hợp, hệ thống có thể thay đổi mức độ quan trọng dựa trên các yếu tố khác và người dùng luôn có thể xác định lại mức độ quan trọng cho một kênh nhất định.
Để biết thêm thông tin về ý nghĩa của các cấp độ, hãy đọc về các cấp độ quan trọng của thông báo.
Đặt thao tác nhấn vào thông báo
Mọi thông báo đều phải phản hồi một lượt nhấn, thường là để mở một hoạt động trong ứng dụng của bạn tương ứng với thông báo đó. Để làm vậy, hãy chỉ định một ý định về nội dung được xác định bằng đối tượng PendingIntent
và truyền đối tượng đó đến setContentIntent()
.
Đoạn mã sau đây cho biết cách tạo một ý định cơ bản để mở một hoạt động khi người dùng nhấn vào thông báo:
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);
Mã này gọi setAutoCancel()
, mã này sẽ tự động xoá thông báo khi người dùng nhấn vào thông báo đó.
Các cờ ý định trong ví dụ trước đó duy trì trải nghiệm điều hướng mà người dùng mong đợi sau khi người dùng mở ứng dụng của bạn bằng thông báo. Bạn có thể muốn sử dụng phương thức này tuỳ thuộc vào loại hoạt động mà bạn đang bắt đầu. Loại hoạt động này có thể là một trong những loại sau:
Một hoạt động chỉ dành riêng cho việc phản hồi thông báo. Không có lý do gì khiến người dùng chuyển đến hoạt động này trong quá trình sử dụng ứng dụng bình thường, vì vậy, hoạt động này sẽ bắt đầu một tác vụ mới thay vì được thêm vào tác vụ và ngăn xếp quay lại hiện có của ứng dụng. Đây là loại ý định được tạo trong mẫu trước đó.
Một hoạt động có trong quy trình ứng dụng thông thường của ứng dụng. Trong trường hợp này, việc bắt đầu hoạt động sẽ tạo một ngăn xếp quay lại để người dùng có thể sử dụng nút Quay lại và nút Lên như mong đợi.
Để biết thêm về các cách định cấu hình ý định của thông báo, hãy xem phần Bắt đầu một hoạt động từ thông báo.
Hiện thông báo
Để thông báo xuất hiện, hãy gọi NotificationManagerCompat.notify()
, truyền cho thông báo một mã nhận dạng duy nhất và kết quả của NotificationCompat.Builder.build()
.
Lệnh này được minh hoạ trong ví dụ sau:
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()) }
Lưu mã nhận dạng thông báo mà bạn truyền đến NotificationManagerCompat.notify()
, vì bạn cần mã này khi muốn cập nhật hoặc xoá thông báo.
Ngoài ra, để kiểm thử các thông báo cơ bản trên thiết bị chạy Android 13 trở lên, hãy bật thông báo theo cách thủ công hoặc tạo một hộp thoại để yêu cầu thông báo.
Thêm nút hành động
Thông báo có thể cung cấp tối đa 3 nút thao tác để người dùng phản hồi nhanh, chẳng hạn như tạm ẩn lời nhắc hoặc trả lời tin nhắn văn bản. Tuy nhiên, các nút thao tác này không được trùng lặp với thao tác được thực hiện khi người dùng nhấn vào thông báo.
Hình 3. Một thông báo có một nút hành động.
Để thêm một nút hành động, hãy truyền một PendingIntent
đến phương thức addAction()
. Thao tác này tương tự như việc thiết lập thao tác mặc định khi nhấn vào thông báo, ngoại trừ việc thay vì chạy một hoạt động, bạn có thể làm những việc khác như bắt đầu một BroadcastReceiver
thực hiện một công việc ở chế độ nền để thao tác này không làm gián đoạn ứng dụng đang mở.
Ví dụ: mã sau đây cho biết cách gửi một thông báo truyền tin đến một receiver cụ thể:
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) 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); 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);
Để biết thêm thông tin về cách tạo một BroadcastReceiver
để chạy hoạt động ở chế độ nền, hãy xem bài viết Tổng quan về chương trình phát sóng.
Nếu bạn đang cố gắng tạo một thông báo có các nút phát nội dung nghe nhìn (chẳng hạn như để tạm dừng và bỏ qua các bản nhạc), hãy xem cách tạo thông báo có các nút điều khiển nội dung nghe nhìn.
Thêm thao tác trả lời trực tiếp
Hành động trả lời trực tiếp (ra mắt trong Android 7.0 (API cấp 24)) cho phép người dùng nhập văn bản trực tiếp vào thông báo. Sau đó, văn bản sẽ được gửi đến ứng dụng của bạn mà không cần mở một hoạt động. Ví dụ: bạn có thể dùng thao tác trả lời trực tiếp để cho phép người dùng trả lời tin nhắn văn bản hoặc cập nhật danh sách việc cần làm ngay trong thông báo.
Hình 4. Khi bạn nhấn vào nút "Trả lời", chế độ nhập văn bản sẽ mở ra.
Thao tác trả lời trực tiếp xuất hiện dưới dạng một nút bổ sung trong thông báo, nút này sẽ mở một phương thức nhập văn bản. Khi người dùng nhập xong, hệ thống sẽ đính kèm phản hồi bằng văn bản vào ý định mà bạn chỉ định cho thao tác thông báo và gửi ý định đó đến ứng dụng của bạn.
Thêm nút trả lời
Để tạo một thao tác thông báo hỗ trợ tính năng trả lời trực tiếp, hãy làm theo các bước sau:
- Tạo một thực thể của
RemoteInput.Builder
mà bạn có thể thêm vào thao tác thông báo. Hàm khởi tạo của lớp này chấp nhận một chuỗi mà hệ thống dùng làm khoá cho dữ liệu đầu vào văn bản. Sau đó, ứng dụng của bạn sẽ dùng khoá đó để truy xuất văn bản của dữ liệu đầu vào.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();
- Tạo một
PendingIntent
cho thao tác trả lời.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);
- Đính kèm đối tượng
RemoteInput
vào một thao tác bằng cách sử dụngaddRemoteInput()
.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();
- Áp dụng thao tác cho một thông báo và phát hành thông báo đó.
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);
Hệ thống sẽ nhắc người dùng nhập câu trả lời khi họ kích hoạt thao tác thông báo, như minh hoạ trong hình 4.
Truy xuất thông tin đầu vào của người dùng từ câu trả lời
Để nhận thông tin đầu vào của người dùng từ giao diện người dùng trả lời của thông báo, hãy gọi RemoteInput.getResultsFromIntent()
, truyền cho thông báo đó Intent
mà BroadcastReceiver
của bạn nhận được:
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; }
Sau khi xử lý văn bản, hãy cập nhật thông báo bằng cách gọi NotificationManagerCompat.notify()
bằng cùng một mã nhận dạng và thẻ (nếu có). Điều này là cần thiết để ẩn giao diện người dùng trả lời trực tiếp và xác nhận với người dùng rằng câu trả lời của họ đã được nhận và xử lý chính xác.
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);
Khi làm việc với thông báo mới này, hãy sử dụng ngữ cảnh được truyền đến phương thức onReceive()
của receiver.
Thêm câu trả lời vào cuối thông báo bằng cách gọi setRemoteInputHistory()
.
Tuy nhiên, nếu bạn đang tạo một ứng dụng nhắn tin, hãy tạo một thông báo theo kiểu nhắn tin và thêm tin nhắn mới vào cuộc trò chuyện.
Để biết thêm lời khuyên về thông báo của ứng dụng nhắn tin, hãy xem phần về các phương pháp hay nhất cho ứng dụng nhắn tin.
Hiện thông báo khẩn cấp
Ứng dụng của bạn có thể cần hiển thị một thông báo khẩn cấp, nhạy cảm về thời gian, chẳng hạn như cuộc gọi điện thoại đến hoặc chuông báo đang đổ chuông. Trong những trường hợp này, bạn có thể liên kết một ý định toàn màn hình với thông báo của mình.
Khi thông báo được gọi, người dùng sẽ thấy một trong những thông báo sau, tuỳ thuộc vào trạng thái khoá của thiết bị:
- Nếu thiết bị của người dùng đang ở chế độ khoá, thì một hoạt động ở chế độ toàn màn hình sẽ xuất hiện, che phủ màn hình khoá.
- Nếu thiết bị của người dùng đang ở trạng thái mở khoá, thông báo sẽ xuất hiện ở dạng mở rộng, bao gồm các lựa chọn để xử lý hoặc đóng thông báo.
Đoạn mã sau đây minh hoạ cách liên kết thông báo với một ý định toàn màn hình:
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);
Đặt chế độ hiển thị màn hình khoá
Để kiểm soát mức độ chi tiết xuất hiện trong thông báo trên màn hình khoá, hãy gọi setVisibility()
và chỉ định một trong các giá trị sau:
VISIBILITY_PUBLIC
: toàn bộ nội dung của thông báo sẽ xuất hiện trên màn hình khoá.VISIBILITY_SECRET
: không có phần nào của thông báo xuất hiện trên màn hình khoá.VISIBILITY_PRIVATE
: chỉ thông tin cơ bản, chẳng hạn như biểu tượng của thông báo và tiêu đề nội dung, xuất hiện trên màn hình khoá. Nội dung đầy đủ của thông báo không xuất hiện.
Khi đặt VISIBILITY_PRIVATE
, bạn cũng có thể cung cấp một phiên bản thay thế của nội dung thông báo để ẩn một số thông tin chi tiết. Ví dụ: một ứng dụng SMS có thể hiển thị thông báo cho biết "Bạn có 3 tin nhắn văn bản mới", nhưng ẩn nội dung và người gửi tin nhắn. Để cung cấp thông báo thay thế này, trước tiên, hãy tạo thông báo thay thế bằng NotificationCompat.Builder
như bình thường. Sau đó, hãy đính kèm thông báo thay thế vào thông báo thông thường bằng setPublicVersion()
.
Xin lưu ý rằng người dùng luôn có quyền kiểm soát cuối cùng đối với việc thông báo của họ có xuất hiện trên màn hình khoá hay không và có thể kiểm soát thông báo dựa trên các kênh thông báo của ứng dụng.
Cập nhật thông báo
Để cập nhật một thông báo sau khi bạn phát hành, hãy gọi lại NotificationManagerCompat.notify()
, truyền cho thông báo đó cùng một mã nhận dạng mà bạn đã dùng trước đó. Nếu thông báo trước đó bị đóng, thì một thông báo mới sẽ được tạo thay thế.
Bạn có thể tuỳ ý gọi setOnlyAlertOnce()
để thông báo của bạn làm gián đoạn người dùng (bằng âm thanh, chế độ rung hoặc tín hiệu trực quan) chỉ trong lần đầu tiên thông báo xuất hiện và không phải cho các bản cập nhật sau này.
Xoá thông báo
Thông báo vẫn hiển thị cho đến khi một trong các trường hợp sau xảy ra:
- Người dùng đóng thông báo.
- Người dùng nhấn vào thông báo, nếu bạn gọi
setAutoCancel()
khi tạo thông báo. - Bạn gọi
cancel()
cho một mã nhận dạng thông báo cụ thể. Phương thức này cũng xoá các thông báo đang diễn ra. - Bạn gọi
cancelAll()
, thao tác này sẽ xoá tất cả thông báo bạn đã phát hành trước đó. - Thời lượng đã chỉ định sẽ trôi qua nếu bạn đặt thời gian chờ khi tạo thông báo bằng cách sử dụng
setTimeoutAfter()
. Nếu cần, bạn có thể huỷ thông báo trước khi hết khoảng thời gian chờ đã chỉ định.
Các phương pháp hay nhất cho ứng dụng nhắn tin
Hãy cân nhắc các phương pháp hay nhất được liệt kê ở đây khi tạo thông báo cho ứng dụng nhắn tin và trò chuyện.
Sử dụng MessagingStyle
Kể từ Android 7.0 (API cấp 24), Android cung cấp một mẫu kiểu thông báo dành riêng cho nội dung nhắn tin. Khi sử dụng lớp NotificationCompat.MessagingStyle
, bạn có thể thay đổi một số nhãn xuất hiện trên thông báo, bao gồm cả tiêu đề cuộc trò chuyện, các thông báo bổ sung và khung hiển thị nội dung cho thông báo.
Đoạn mã sau đây minh hoạ cách tuỳ chỉnh kiểu của một thông báo bằng cách sử dụng lớp 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();
Kể từ Android 9.0 (API cấp 28), bạn cũng phải sử dụng lớp Person
để có được chế độ hiển thị tối ưu cho thông báo và hình đại diện của thông báo.
Khi sử dụng NotificationCompat.MessagingStyle
, hãy làm như sau:
- Gọi
MessagingStyle.setConversationTitle()
để đặt tiêu đề cho cuộc trò chuyện nhóm có từ 3 người trở lên. Tiêu đề cuộc trò chuyện phù hợp có thể là tên của cuộc trò chuyện nhóm hoặc nếu không có tên, thì đó là danh sách những người tham gia cuộc trò chuyện. Nếu không có thông tin này, tin nhắn có thể bị nhầm lẫn là thuộc về cuộc trò chuyện riêng tư với người gửi tin nhắn gần đây nhất trong cuộc trò chuyện. - Sử dụng phương thức
MessagingStyle.setData()
để thêm các thông báo đa phương tiện, chẳng hạn như hình ảnh. Các loại MIME của hình ảnh mẫu/* được hỗ trợ.
Sử dụng tính năng Trả lời trực tiếp
Tính năng Trả lời trực tiếp cho phép người dùng trả lời tin nhắn ngay trong thông báo.
- Sau khi người dùng trả lời bằng thao tác trả lời cùng dòng, hãy dùng
MessagingStyle.addMessage()
để cập nhật thông báoMessagingStyle
và không rút lại hoặc huỷ thông báo. Nếu không huỷ thông báo, người dùng có thể gửi nhiều câu trả lời từ thông báo. - Để làm cho thao tác trả lời cùng dòng tương thích với Wear OS, hãy gọi
Action.WearableExtender.setHintDisplayInlineAction(true)
. - Sử dụng phương thức
addHistoricMessage()
để cung cấp bối cảnh cho cuộc trò chuyện trả lời trực tiếp bằng cách thêm các tin nhắn trước đây vào thông báo.
Bật tính năng Trả lời thông minh
- Để bật tính năng Trả lời thông minh, hãy gọi
setAllowGeneratedResponses(true)
trên thao tác trả lời. Điều này giúp người dùng có thể sử dụng các câu trả lời thông minh khi thông báo được chuyển tiếp đến thiết bị Wear OS. Các câu trả lời của tính năng Trả lời thông minh được tạo bởi một mô hình học máy hoàn toàn trên đồng hồ bằng cách sử dụng ngữ cảnh do thông báoNotificationCompat.MessagingStyle
cung cấp và không có dữ liệu nào được tải lên Internet để tạo các câu trả lời.
Thêm siêu dữ liệu thông báo
- Chỉ định siêu dữ liệu thông báo để cho hệ thống biết cách xử lý thông báo của ứng dụng khi thiết bị ở trạng thái
Do Not Disturb mode
. Ví dụ: sử dụng phương thứcaddPerson()
hoặcsetCategory(Notification.CATEGORY_MESSAGE)
để ghi đè chế độ Không làm phiền.