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 của bạn khi nó hiện không được sử dụng. Tài liệu này hướng dẫn bạn cách tạo thông báo bằng các tính năng khác nhau. Để xem 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. Để biết mã mẫu sử dụng thông báo, hãy xem phần Mọi người mẫu trên GitHub.
Mã trong trang này sử dụng
NotificationCompat
API trong Thư viện AndroidX. Các API này cho phép bạn thêm các tính năng chỉ có sẵn
trên các phiên bản Android mới hơn trong khi vẫn cung cấp khả năng tương thích trở lại cho 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 tại chỗ,
khiến các phiên bản trước đó không hoạt động.
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ó những thông tin cần thiết
để sử dụng NotificationCompat
, hãy xác minh rằng
cấp mô-đun của bạn
Tệp build.gradle
bao gồm phần phụ thuộc sau:
Groovy
dependencies { implementation "androidx.core:core:2.2.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:2.2.0") }
Tạo một thông báo cơ bản
Là thông báo có hình thức cơ bản và ngắn gọn nhất, còn gọi là thu gọn biểu mẫu – hiển thị một biểu tượng, tiêu đề và một lượng nhỏ nội dung văn bản. Chiến dịch này cho biết cách tạo một thông báo mà người dùng có thể nhấn để chạy hoạt động trong ứng dụng của bạn.
Hình 1. Thông báo có biểu tượng, tiêu đề và một số văn bản.
Để biết thêm chi tiết về từng phần của thông báo, hãy đọc về thông báo cấu trúc.
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 các thông báo không được miễn trừ (bao gồm cả thông báo về 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ề các quyền khi bắt đầu chạy, hãy xem Quyền khi bắt đầu chạy thông báo.
Đặt nội dung thông báo
Để bắt đầu, hãy đặt kênh và nội dung của thông báo bằng
NotificationCompat.Builder
. Ví dụ sau đây minh hoạ cách tạo thông báo bằng
sau:
Một biểu tượng nhỏ, được đặt bởi
setSmallIcon()
. Đây là nội dung duy nhất hiển thị cho người dùng mà người dùng cần phải có.Tiêu đề, do
setContentTitle()
.Văn bản nội dung, được đặt bởi
setContentText()
.Mức độ ưu tiên của thông báo, được đặt bởi
setPriority()
. 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 và trước đó. Đối với Android 8.0 trở lên, hãy đặt tầm quan trọng của kênh thành được trình bày 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 khởi tạo NotificationCompat.Builder
yêu cầu bạn cung cấp một kênh
Mã nhận dạng. Đây là yêu cầu bắt buộc để tương thích với Android 8.0 (API cấp 26) và
sau này nhưng bị các phiên bản cũ bỏ qua.
Theo mặc định, nội dung văn bản của thông báo sẽ bị cắt bớt để vừa với một dòng. Bạn có thể hiển thị thông tin bổ sung bằng cách tạo thông báo có thể mở rộng.
Hình 2. Có thể mở rộng ở các biểu mẫu được thu gọn và mở rộng.
Nếu muốn thông báo dài hơn, bạn có thể bật
bằng cách thêm một mẫu kiểu với
setStyle()
.
Ví dụ: mã sau đây sẽ tạo 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à bộ điều khiển phát nội dung nghe nhìn, hãy xem Tạo thông báo.
Tạo kênh và đặt tầm quan trọng
Để 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
bằng cách truyền một bản sao của
NotificationChannel
thành
createNotificationChannel()
.
Mã sau đây bị chặn bởi một đ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ỳ nội dung 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 bắt đầu. Việc gọi lệnh này nhiều lần là rất an toàn vì việc tạo một kênh thông báo không thực hiện hoạt động nào.
Hàm khởi tạo NotificationChannel
cần có importance
, sử dụng một trong
hằng số từ
Lớp NotificationManager
. Chiến dịch này
tham số xác định cách làm gián đoạn người dùng đối với bất kỳ thông báo nào thuộc về
đối với kênh này. Đặt mức độ ưu tiên bằng setPriority()
để hỗ trợ Android 7.1
trở về trước, như được thể hiện trong ví dụ trước.
Mặc dù bạn phải thiết lập mức độ quan trọng hoặc mức độ ưu tiên của thông báo như được trình bày trong trong ví dụ sau đây, 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 đối với một của bạn.
Để biết thêm thông tin về ý nghĩa của các cấp độ, hãy đọc bài viết về tầm quan trọng của thông báo cấp độ.
Đặt thao tác nhấn của thông báo
Mọi thông báo phải phản hồi với một lần nhấn, thường là để mở một hoạt động trong
tương ứng với thông báo. Để làm vậy, hãy chỉ định một ý định nội dung
được xác định bằ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);
Đoạn mã này gọi
setAutoCancel()
!
Thao tác này sẽ tự động xoá thông báo khi người dùng nhấn vào thông báo đó.
Phương thức setFlags()
như trong ví dụ trước duy trì thao tác điều hướng dự kiến của người dùng
sau khi mở ứng dụng của bạn bằng thông báo đó. Bạn nên
sử dụng nó tùy thuộc vào loại hoạt động bạn đang bắt đầu, đó có thể là một trong
như sau:
Một hoạt động chỉ tồn tại để phản hồi thông báo. Không có lý do gì để người dùng chuyển đến hoạt động này trong khi dùng ứng dụng như bình thường, để hoạt động bắt đầu một tác vụ mới thay vì được thêm vào ứng dụng việc cần làm và quay lại hiện tại ngăn xếp. Đây là loại ý định đã tạo trong mẫu trước.
Một hoạt động tồn tại trong luồng ứ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 lui để kỳ vọng của người dùng cho nút Quay lại và Mũi tên lên là không bị ảnh hưởng.
Để biết thêm về các cách định cấu hình ý định của thông báo, hãy xem Bắt đầu 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 nó một ID duy nhất cho thông báo 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ã thông báo mà bạn chuyển tới NotificationManagerCompat.notify()
,
bởi vì bạn cần nó khi bạn muốn cập nhật hoặc xóa
thông báo.
Ngoài ra, để kiểm thử các thông báo cơ bản trên những thiết bị chạy trên 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 để thông báo về yêu cầu.
Thêm nút hành động
Một thông báo có thể cung cấp tối đa 3 nút hành động cho phép người dùng phản hồi một cách nhanh chóng, chẳng hạn như tạm hoãn lời nhắc hoặc trả lời tin nhắn văn bản. Tuy nhiên, đây là các nút hành động không được sao chép hành động được thực hiện khi người dùng nhấn thông báo.
Hình 3. Thông báo có một nút hành động.
Để thêm một nút hành động, hãy chuyển PendingIntent
vào
addAction()
. Thao tác này tương tự như thiết lập hành động nhấn mặc định của thông báo, ngoại trừ
thay vì khởi chạy một hoạt động, bạn có thể làm những việc khác như bắt đầu
BroadcastReceiver
đó
thực hiện một công việc trong nền để hành động đó không làm gián đoạn ứng dụng
đã mở.
Ví dụ: mã sau đây biểu thị cách gửi thông báo truyền tin đến một người nhận:
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);
Để biết thêm thông tin về cách tạo BroadcastReceiver
để chạy ở chế độ nền
phù hợp, hãy xem Tổng quan về chương trình phát sóng.
Thay vào đó, nếu bạn đang cố tạo một thông báo bằng các nút phát lại nội dung nghe nhìn, chẳng hạn như để tạm dừng và bỏ qua bản nhạc, hãy xem cách tạo thông báo bằng nội dung nghe nhìn kiểm soát.
Thêm thao tác trả lời trực tiếp
Thao tác trả lời trực tiếp (được giới thiệu trong Android 7.0 (API cấp 24)) cho phép người dùng hãy nhập trực tiếp văn bản vào thông báo. Sau đó, văn bản này được gửi đến ứng dụng của bạn mà không cần mở hoạt động nào. Ví dụ: bạn có thể sử 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 công việc từ trong .
Hình 4. Nhấn vào "Trả lời" sẽ mở trình nhập văn bản.
Hành động 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 sẽ mở ra một mục nhập văn bản. Khi người dùng nhập xong, hệ thống sẽ đính kèm văn bản đó phản hồi ý định mà bạn chỉ định cho hành động thông báo và gửi đối với ứ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ợ việc 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 hành động thông báo. Hàm khởi tạo của lớp này chấp nhận chuỗi mà hệ thống sử dụng làm khoá để nhập văn bản. Ứng dụng của bạn sau này sẽ sử dụng khoá đó để truy xuất văn bản đầ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
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
RemoteInput
đối tượng với một hành động 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 đối với một thông báo rồi đưa ra 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 phản hồi khi họ kích hoạt hành động gửi thông báo, như được minh hoạ trong hình 4.
Truy xuất hoạt động đầu vào của người dùng từ câu trả lời
Để nhận hoạt động đầ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()
!
chuyển phương thức này Intent
mà BroadcastReceiver
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 bạn xử lý tin nhắn văn bản, hãy cập nhật thông báo bằng cách gọi
NotificationManagerCompat.notify()
có cùng mã và thẻ (nếu sử dụng). Đây là
để ẩ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 chuyển đến
của người nhận
onReceive()
.
Thêm câu trả lời vào phần dưới cùng của thông báo bằng cách gọi
setRemoteInputHistory()
.
Tuy nhiên, nếu bạn đang tạo ứng dụng nhắn tin, hãy tạo kiểu nhắn tin
thông báo và thêm
thư mới vào cuộc trò chuyện.
Để biết thêm lời khuyên về các 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.
Thêm thanh tiến trình
Thông báo có thể bao gồm chỉ báo tiến trình dạng ảnh động cho người dùng biết trạng thái của một hoạt động đang diễn ra.
Hình 5. Thanh tiến trình trong khoảng thời gian một thao tác.
Nếu bạn có thể ước tính số lượng hoạt động sẽ hoàn thành vào bất kỳ thời điểm nào, hãy sử dụng
"xác định" dạng chỉ báo (như trong Hình 5) bằng cách gọi
setProgress(max, progress,
false)
.
Tham số đầu tiên là giá trị "hoàn tất" chẳng hạn như 100. Thứ hai là
mức độ hoàn tất. URL cuối cùng cho biết đây là tiến trình xác định
thanh.
Khi thao tác của bạn tiếp tục, hãy liên tục gọi setProgress(max, progress,
false)
với giá trị cập nhật cho progress
và gửi lại thông báo như
như trong ví dụ sau.
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());
Khi kết thúc thao tác, progress
phải bằng max
. Bạn có thể để
thanh tiến trình để cho biết thao tác đã hoàn tất hoặc xoá thao tác đó. Trong cả hai trường hợp,
cập nhật nội dung thông báo để cho biết rằng thao tác đã hoàn tất. Để xoá
thanh tiến trình, hãy gọi setProgress(0, 0, false)
.
Để hiển thị một thanh tiến trình không xác định (thanh không chỉ ra việc hoàn thành)
phần trăm), hãy gọi setProgress(0, 0, true)
. Kết quả thu được là một chỉ báo có
có cùng kiểu như thanh tiến trình trước đó, ngoại trừ việc đó là một thanh tiến trình liên tục
ảnh động không cho biết đã hoàn thành. Ảnh động tiến trình chạy cho đến
bạn gọi setProgress(0, 0, false)
, sau đó cập nhật thông báo để xoá
chỉ báo hoạt động.
Hãy nhớ thay đổi nội dung thông báo để cho biết thao tác đã hoàn tất.
Đặt danh mục trên toàn hệ thống
Android sử dụng các danh mục được xác định trước trên toàn hệ thống để xác định xem có nên làm phiền hay không người dùng nhận được thông báo cụ thể khi người dùng bật chế độ Không làm phiền chế độ xem.
Nếu thông báo của bạn thuộc một trong các loại thông báo được xác định trong
NotificationCompat
—chẳng hạn như
CATEGORY_ALARM
,
CATEGORY_REMINDER
,
CATEGORY_EVENT
,
hoặc
CATEGORY_CALL
— khai báo
bằng cách chuyển danh mục thích hợp cho
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);
Hệ thống sử dụng thông tin này về loại thông báo của bạn để
quyết định về việc hiển thị thông báo của bạn khi thiết bị ở chế độ Không
Làm phiền. Tuy nhiên, bạn không bắt buộc phải đặt danh mục trên toàn hệ thống. Chỉ làm như vậy
nếu các thông báo của bạn khớp với một trong các danh mục được xác định trong
NotificationCompat
.
Hiện tin nhắn 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 và có giới hạn thời gian, chẳng hạn như cuộc gọ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 ý định toàn màn hình bằng 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 các điều 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 bị khoá, một hoạt động toàn màn hình sẽ xuất hiện, che màn hình khoá.
- Nếu thiết bị của người dùng được mở khoá, thông báo sẽ xuất hiện trong giao diện mở rộng biểu mẫu bao gồm các tuỳ 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 của bạn với ý đị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 hiển thị trong thông báo từ màn hình khoá,
cuộc 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 hiển thị trên màn hình khoá.VISIBILITY_PRIVATE
: chỉ những thông tin cơ bản như biểu tượng của thông báo và nội dung tiêu đề, hiển thị trên màn hình khoá. Toàn bộ nội dung của thông báo không chương trình.
Khi đặt VISIBILITY_PRIVATE
, bạn cũng có thể cung cấp 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 nhất định. Ví dụ: ứng dụng SMS
có thể hiển thị thông báo "Bạn có 3 tin nhắn văn bản mới" nhưng
ẩn nội dung thư và người gửi. Để cung cấp phương án thay thế này
trước tiên, hãy tạo thông báo thay thế bằng
NotificationCompat.Builder
như thường lệ. Sau đó, đính kèm thông báo thay thế
sang 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 hiển thị trên màn hình khóa và có thể kiểm soát các thông báo này dựa vào kênh thông báo của ứng dụng.
Cập nhật thông báo
Để cập nhật thông báo sau khi gửi thông báo, hãy gọi
NotificationManagerCompat.notify()
một lần nữa, truyền vào đó cùng một mã nhận dạng mà bạn đã sử dụng
trước đó. Nếu thông báo trước đó bị loại bỏ thì 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, rung hoặc hình ảnh
gợi ý—chỉ lần đầu tiên thông báo xuất hiện chứ không phải lần sau
bản cập nhật.
Xoá thông báo
Thông báo vẫn hiển thị cho đến khi một trong những điều 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ã thông báo cụ thể. Phương thức này cũng xoá các từ khoá liên tục thông báo. - Bạn gọi
cancelAll()
! Thao tác này sẽ xoá tất cả các thông báo mà bạn đã gửi trước đây. - Thời lượng đã chỉ định kết thúc, nếu bạn đặt thời gian chờ khi tạo
thông báo, đang sử dụng
setTimeoutAfter()
. Nếu cần, bạn có thể huỷ thông báo trước thời gian chờ đã chỉ định thời lượng trôi qua.
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ê tại đây khi tạo thông báo cho nhắn tin và trò chuyện.
Sử dụng MessagingStyle
Kể từ Android 7.0 (API cấp 24), Android sẽ cung cấp một kiểu thông báo
mẫu dành riêng cho nội dung nhắn tin. Sử dụng
NotificationCompat.MessagingStyle
bạn có thể thay đổi một số nhãn hiển thị trên thông báo,
bao gồm tiêu đề cuộc trò chuyện, thư bổ sung và chế độ xem nội dung cho
thông báo đó.
Đoạn mã sau đây minh hoạ cách tuỳ chỉnh kiểu của 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
Person
để nhận được
hiển thị tối ưu 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 điện
MessagingStyle.setConversationTitle()
để đặt tiêu đề cho cuộc trò chuyện nhóm có nhiều hơn 2 người. Tốt tiêu đề cuộc trò chuyện có thể là tên của cuộc trò chuyện nhóm hoặc nếu không phải có tên, danh sách những người tham gia cuộc trò chuyện. Nếu không có điều này, thư có thể bị nhầm lẫn là thuộc về một cuộc trò chuyện trực tiếp với người gửi thư gần đây nhất trong cuộc trò chuyện. - Sử dụng
MessagingStyle.setData()
để bao gồm thông điệp đa phương tiện như hình ảnh. Loại MIME của mẫu image/* đượ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 cùng dòng cho thư.
- Sau khi người dùng trả lời bằng thao tác trả lời cùng dòng, hãy sử dụng
MessagingStyle.addMessage()
để cập nhật thông báoMessagingStyle
và không rút lại hoặc huỷ . Nếu không huỷ thông báo, người dùng có thể gửi nhiều các câu trả lời từ thông báo. - Để 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
addHistoricMessage()
nhằm cung cấp ngữ cảnh cho một cuộc trò chuyện trả lời trực tiếp bằng cách thêm tin nhắn đến 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)
đối với thao tác trả lời. Điều này khiến cho tính năng Trả lời thông minh có sẵn cho người dùng khi thông báo được kết nối với thiết bị Wear OS. Trả lời thông minh các câu trả lời được tạo ra bằng 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 doNotificationCompat.MessagingStyle
cung cấp và không có dữ liệu nào được tải lên Internet để tạo phản hồ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ý ứng dụng của bạn
thông báo khi thiết bị ở
Do Not Disturb mode
. Ví dụ: sử dụngaddPerson()
hoặcsetCategory(Notification.CATEGORY_MESSAGE)
để ghi đè chế độ Không làm phiền.