Thông báo là một thông điệp bạn có thể hiển thị với người dùng bên ngoài UI bình thường của ứng dụng của bạn. Khi bạn yêu cầu hệ thống phát hành một thông báo, trước tiên nó xuất hiện như một biểu tượng trong khu vực thông báo. Để xem chi tiết thông báo, người dùng mở ngăn kéo thông báo. Cả khu vực thông báo và ngăn kéo thông báo đều là các khu vực do hệ thống kiểm soát mà người dùng có thể xem vào bất cứ lúc nào.
Hình 1. Thông báo trong khu vực thông báo.
Hình 2. Thông báo trong ngăn kéo thông báo.
Lưu ý: Ngoại trừ phần được lưu ý, hướng dẫn này nhắc đến
lớp NotificationCompat.Builder
trong phiên bản 4 của Thư viện Hỗ trợ.
Lớp Notification.Builder đã được thêm vào trong Android
3.0 (API mức 11).
Cân nhắc Thiết kế
Là một phần quan trọng của giao diện người dùng Android, thông báo có các hướng dẫn thiết kế của riêng mình. Những thay đổi thiết kế cơ bản được giới thiệu trong Android 5.0 (API mức 21) đặc biệt quan trọng và bạn nên xem phần đào tạo về Thiết kế Material để biết thêm thông tin. Để tìm hiểu cách thiết kế thông báo và tương tác của chúng, hãy đọc hướng dẫn thiết kế Thông báo.
Tạo một Thông báo
Bạn quy định thông tin UI và các hành động cho một thông báo trong một đối tượng
NotificationCompat.Builder.
Để tạo chính thông báo, bạn gọi
NotificationCompat.Builder.build(),
nó sẽ trả về một đối tượng Notification chứa những đặc tả của bạn. Để phát hành
thông báo, bạn chuyển đối tượng Notification tới hệ thống bằng cách gọi
NotificationManager.notify().
Nội dung thông báo được yêu cầu
Một đối tượng Notification phải chứa những điều sau:
-
Một biểu tượng nhỏ được đặt bởi
setSmallIcon() -
Một tiêu đề được đặt bởi
setContentTitle() -
Văn bản chi tiết được đặt bởi
setContentText()
Nội dung và cài đặt thông báo tùy chọn
Tất cả cài đặt và nội dung thông báo khác đều mang tính tùy chọn. Để tìm hiểu thêm về chúng,
hãy xem tài liệu tham khảo cho NotificationCompat.Builder.
Hành động thông báo
Mặc dù chúng mang tính tùy chọn, bạn nên thêm ít nhất một hành động vào thông báo của mình.
Một hành động cho phép người dùng đi trực tiếp từ thông báo tới một
Activity trong ứng dụng của bạn, nơi mà họ có thể xem thêm một hoặc nhiều sự kiện
hoặc làm việc thêm.
Một thông báo có thể cung cấp nhiều hành động. Bạn nên luôn định nghĩa hành động mà được
kích khởi khi người dùng nhấp vào thông báo; thường thì hành động này mở ra một
Activity trong ứng dụng của bạn. Bạn cũng có thể thêm các nút vào thông báo
để thực hiện những hành động bổ sung chẳng hạn như báo lại báo thức hay hồi đáp ngay lập tức một tin nhắn
văn bản; tính năng này sẵn có từ phiên bản Android 4.1. Nếu sử dụng các nút hành động bổ sung, bạn
cũng phải cung cấp tính năng của chúng trong một Activity trong ứng dụng của bạn; xem
phần Xử lý tính tương thích để biết thêm chi tiết.
Bên trong một Notification, bản thân hành động được định nghĩa bởi một
PendingIntent chứa một
Intent có chức năng bắt đầu
một Activity trong ứng dụng của bạn. Để liên kết
PendingIntent với một cử chỉ, hãy gọi phương pháp
NotificationCompat.Builder phù hợp. Ví dụ, nếu bạn muốn bắt đầu
Activity khi người dùng nhấp vào văn bản thông báo trong
ngăn kéo thông báo, bạn hãy thêm PendingIntent bằng cách gọi
setContentIntent().
Bắt đầu một Activity khi người dùng nhấp vào thông báo là kịch bản
hành động phổ biến nhất. Bạn cũng có thể bắt đầu một Activity khi người dùng
bỏ một thông báo. Trong phiên bản Android 4.1 và sau đó, bạn có thể bắt đầu một
Activity từ một nút hành động. Để tìm hiểu thêm, hãy đọc hướng dẫn tham khảo cho
NotificationCompat.Builder.
Mức ưu tiên của thông báo
Nếu muốn, bạn có thể đặt mức ưu tiên của một thông báo. Mức ưu tiên đóng vai trò
như một gợi ý cho UI của thiết bị về cách thông báo sẽ được hiển thị.
Để đặt mức ưu tiên của một thông báo, hãy gọi NotificationCompat.Builder.setPriority() và chuyển trong một trong các hằng số mức ưu tiên NotificationCompat. Có năm mức ưu tiên,
dao động từ PRIORITY_MIN (-2) đến PRIORITY_MAX (2); nếu không được đặt,
mức ưu tiên mặc định thành PRIORITY_DEFAULT (0).
Để biết thông tin về việc đặt một mức ưu tiên phù hợp, hãy xem phần "Đặt và quản lý mức ưu tiên của thông báo cho đúng" trong hướng dẫn Thiết kế Thông báo .
Tạo một thông báo đơn giản
Đoạn mã HTML sau minh họa một thông báo đơn giản, trong đó quy định một hoạt động sẽ mở khi
người dùng nhấp vào thông báo. Để ý rằng đoạn mã này sẽ tạo một đối tượng
TaskStackBuilder và sử dụng nó để tạo
PendingIntent cho hành động. Kiểu mẫu này được giải thích chi tiết hơn
trong phần
Giữ lại Điều hướng khi Bắt đầu một Hoạt động:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());
Vậy là xong. Người dùng của bạn hiện đã được thông báo.
Áp dụng bố trí mở rộng cho một thông báo
Để có một thông báo xuất hiện trong một dạng xem mở rộng, trước tiên hãy tạo một đối tượng
NotificationCompat.Builder với các tùy chọn dạng xem thông thường
mà bạn muốn. Tiếp theo, hãy gọi Builder.setStyle() với một đối tượng bố trí mở rộng làm tham đối.
Ghi nhớ rằng các thông báo mở rộng không sẵn có trên các nền tảng trước Android 4.1. Để tìm hiểu về cách xử lý thông báo đối với nền tảng phiên bản Android 4.1 và trước đó, hãy đọc phần Xử lý tính tương thích.
Ví dụ, đoạn mã HTML sau minh họa cách thay đổi thông báo được tạo trong đoạn mã HTML trước để sử dụng bố trí mở rộng:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Event tracker")
.setContentText("Events received")
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
String[] events = new String[6];
// Sets a title for the Inbox in expanded layout
inboxStyle.setBigContentTitle("Event tracker details:");
...
// Moves events into the expanded layout
for (int i=0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
mBuilder.setStyle(inBoxStyle);
...
// Issue the notification here.
Xử lý tính tương thích
Không phải tất cả tính năng thông báo đều sẵn có đối với một phiên bản cụ thể, mặc dù
các phương pháp đặt chúng đều nằm trong lớp thư viện hỗ trợ
NotificationCompat.Builder.
Ví dụ, nút hành động phụ thuộc vào thông báo mở rộng chỉ xuất hiện trên phiên bản Android
4.1 trở lên, bởi bản thân thông báo mở rộng chỉ sẵn có trên phiên bản
Android 4.1 trở lên.
Để đảm bảo tính tương thích tốt nhất, hãy tạo thông báo bằng
NotificationCompat và các lớp con của nó,
đặc biệt là NotificationCompat.Builder. Bên cạnh đó, hãy tuân theo tiến trình sau khi bạn triển khai một thông báo:
-
Cung cấp tất cả tính năng thông báo cho tất cả người dùng, không phụ thuộc vào phiên bản
mà họ đang sử dụng. Để làm vậy, hãy xác minh rằng tất cả tính năng đều sẵn có từ một
Activitytrong ứng dụng của bạn. Bạn có thể muốn thêm mộtActivitymới để làm điều này.Ví dụ, nếu bạn muốn sử dụng
addAction()để cung cấp khả năng điều khiển dừng và bắt đầu phát lại phương tiện, trước tiên hãy triển khai khả năng điều khiển này trong mộtActivitytrong ứng dụng của bạn. -
Đảm bảo rằng tất cả người dùng đều có thể tiếp cận với tính năng trong
Activity, bằng cách cho nó khởi động khi người dùng nhấp vào thông báo. Để làm điều này, hãy tạo mộtPendingIntentchoActivity. GọisetContentIntent()để thêmPendingIntentvào thông báo. -
Bây giờ, hãy thêm các tính năng thông báo mở rộng mà bạn muốn sử dụng vào thông báo. Ghi nhớ
rằng bất kỳ tính năng nào mà bạn thêm cũng phải sẵn có trong
Activitymà bắt đầu khi người dùng nhấp vào thông báo.
Quản lý Thông báo
Khi cần phát hành một thông báo nhiều lần cho cùng loại sự kiện, bạn nên tránh tạo một thông báo hoàn toàn mới. Thay vào đó, bạn nên cân nhắc cập nhật một thông báo trước đó, hoặc bằng cách thay đổi một vài giá trị hoặc bằng cách thêm vào nó, hoặc cả hai.
Ví dụ, Gmail thông báo với người dùng rằng e-mail mới đã đến bằng cách tăng số đếm tin nhắn chưa đọc và bằng cách thêm một phần tóm tắt từng e-mail vào thông báo. Đây được gọi là "xếp chồng" thông báo; nó được mô tả chi tiết hơn trong phần hướng dẫn Thiết kế Thông báo.
Lưu ý: Tính năng Gmail này yêu cầu bố trí mở rộng "hộp thư đến", đó là một phần của tính năng thông báo mở rộng sẵn có bắt đầu từ Android 4.1.
Phần sau mô tả cách cập nhật thông báo và cả cách loại bỏ chúng.
Cập nhật thông báo
Để thiết lập một thông báo để nó có thể được cập nhật, hãy phát hành nó cùng một ID thông báo bằng cách gọi
NotificationManager.notify().
Để cập nhật thông báo sau khi bạn đã phát hành
nó, hãy cập nhật hoặc tạo một đối tượng NotificationCompat.Builder,
xây dựng một đối tượng Notification từ nó, và phát hành
Notification với cùng ID mà bạn đã sử dụng trước đó. Nếu
thông báo trước đó vẫn hiển thị, hệ thống sẽ cập nhật nó từ nội dung của
đối tượng Notification. Nếu thông báo trước đó đã bị bỏ đi, một
thông báo mới sẽ được tạo thay thế.
Đoạn mã HTML sau minh họa một thông báo được cập nhật để phản ánh số sự kiện đã xảy ra. Nó xếp chồng thông báo, hiển thị một tóm tắt:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
Loại bỏ thông báo
Thông báo vẫn hiển thị cho tới khi xảy ra một trong những điều sau:
- Người dùng bỏ từng thông báo một hoặc bỏ tất cả bằng cách sử dụng "Xóa Tất cả" (nếu thông báo có thể xóa được).
-
Người dùng nhấp vào thông báo và bạn đã gọi
setAutoCancel()khi tạo thông báo. -
Bạn gọi
cancel()cho một ID thông báo cụ thể. Phương pháp này cũng xóa các thông báo đang diễn ra. -
Bạn gọi
cancelAll(), nó sẽ xóa tất cả thông báo mà bạn đã phát hành trước đó.
Giữ lại Điều hướng khi Bắt đầu một Hoạt động
Khi bạn bắt đầu một Activity từ một thông báo, bạn phải giữ lại trải nghiệm điều hướng kỳ vọng
của người dùng. Nhấp vào Quay lại sẽ đưa người dùng quay lại thông qua
tiến trình làm việc bình thường của ứng dụng về màn hình Trang chủ, và nhấp vào Gần đây sẽ hiển thị
Activity như một tác vụ riêng. Để giữ lại trải nghiệm điều hướng, bạn
nên bắt đầu Activity trong một tác vụ mới. Cách bạn thiết lập
PendingIntent để cấp cho bạn một tác vụ mới sẽ phụ thuộc vào tính chất của
Activity mà bạn đang bắt đầu. Có hai tình huống thông thường:
- Hoạt động thường xuyên
-
Bạn đang bắt đầu một
Activitylà một phần của tiến trình công việc bình thường của ứng dụng. Trong tình huống này, hãy thiết lậpPendingIntentđể bắt đầu một tác vụ mới, và cung cấpPendingIntentvới một ngăn xếp có chức năng tái tạo lại hành vi thông thường Quay lại của ứng dụng.Thông báo từ ứng dụng Gmail thể hiện điều này. Khi bạn nhấp vào một thông báo cho một thư e-mail đơn lẻ, bạn sẽ thấy chính thư đó. Chạm vào Quay lại sẽ đưa bạn ngược lại qua Gmail về màn hình Trang chủ, giống như thể bạn đã vào Gmail từ màn hình Trang chủ chứ không phải vào từ một thông báo.
Điều này xảy ra mà không phụ thuộc vào ứng dụng bạn đang ở trong khi chạm vào thông báo. Ví dụ, nếu bạn đang vào Gmail để soạn thư, và bạn nhấp vào một thông báo cho một e-mail đơn lẻ, bạn sẽ đến e-mail đó ngay lập tức. Chạm vào Quay lại sẽ đưa bạn về hộp thư đến rồi tới màn hình Trang chủ, thay vì đưa bạn tới thư mà bạn đang soạn.
- Hoạt động đặc biệt
-
Người dùng chỉ thấy
Activitynày nếu nó được bắt đầu từ một thông báo. Nghĩa là,Activitymở rộng thông báo bằng cách cung cấp thông tin mà sẽ khó hiển thị trong chính thông báo đó. Đối với tình huống này, hãy thiết lậpPendingIntentđể bắt đầu một tác vụ mới. Tuy nhiên, không cần tạo một ngăn xếp vìActivityđược bắt đầu không phải là một phần trong tiến trình hoạt động của ứng dụng. Nhấp vào Quay lại sẽ vẫn đưa người dùng đến màn hình Trang chủ.
Thiết đặt một PendingIntent cho hoạt động thường xuyên
Để thiết lập PendingIntent để bắt đầu một mục nhập trực tiếp
Activity, hãy làm theo những bước sau:
-
Định nghĩa phân cấp
Activitycủa ứng dụng của bạn trong bản kê khai.-
Thêm hỗ trợ cho phiên bản Android 4.0.3 và trước đó. Để làm điều này, hãy quy định mẹ của
Activitymà bạn đang bắt đầu bằng cách thêm phần tử<meta-data>làm con của<activity>.Đối với phần tử này, hãy đặt
android:name="android.support.PARENT_ACTIVITY". Đặtandroid:value="<parent_activity_name>"trong đó<parent_activity_name>là giá trị củaandroid:nameđối với phần tử<activity>mẹ. Xem ví dụ trong XML sau. -
Cũng thêm hỗ trợ cho phiên bản Android 4.1 và sau đó. Để làm điều này, hãy thêm thuộc tính
android:parentActivityNamevào phần tử<activity>củaActivitymà bạn đang bắt đầu.
XML cuối cùng sẽ trông như sau:
<activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ResultActivity" android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"/> </activity> -
Thêm hỗ trợ cho phiên bản Android 4.0.3 và trước đó. Để làm điều này, hãy quy định mẹ của
-
Tạo một ngăn xếp dựa trên
Intentmà bắt đầuActivity:-
Tạo
Intentđể bắt đầuActivity. -
Tạo một bộ dựng chồng bằng cách gọi
TaskStackBuilder.create(). -
Thêm ngăn xếp vào bộ dựng ngăn xếp bằng cách gọi
addParentStack(). Đối với mỗiActivitytrong phân cấp mà bạn đã định nghĩa trong bản kê khai, ngăn xếp chứa một đối tượngIntentmà sẽ khởi độngActivity. Phương pháp này cũng thêm cờ có chức năng bắt đầu chồng trong một tác vụ mới.Lưu ý: Mặc dù tham đối đến
addParentStack()là một tham chiếu tớiActivityđược bắt đầu, phương pháp gọi không thêmIntentcó chức năng bắt đầuActivity. Thay vào đó, nó được xử lý ở bước tiếp theo. -
Thêm
Intentcó chức năng bắt đầuActivitytừ thông báo bằng cách gọiaddNextIntent(). ChuyểnIntentmà bạn đã tạo ở bước đầu tiên làm tham đối tớiaddNextIntent(). -
Nếu bạn cần, hãy thêm các tham đối tới các đối tượng
Intenttrên chồng bằng cách gọiTaskStackBuilder.editIntentAt(). Đôi khi cần phải đảm bảo rằngActivitymục tiêu sẽ hiển thị dữ liệu có ý nghĩa khi người dùng điều hướng tới nó bằng cách sử dụng Quay lại. -
Nhận một
PendingIntentcho ngăn xếp này bằng cách gọigetPendingIntent(). Sau đó, bạn có thể sử dụngPendingIntentnày làm tham đối tớisetContentIntent().
-
Tạo
Đoạn mã HTML sau minh họa tiến trình:
...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
Thiết đặt một PendingIntent cho hoạt động đặc biệt
Phần sau mô tả cách thiết lập một
PendingIntent cho hoạt động đặc biệt.
Một Activity đặc biệt không cần ngăn xếp, vì thế bạn không phải
định nghĩa phân cấp Activity của nó trong bản kê khai, và bạn không phải
gọi
addParentStack() để xây dựng một
ngăn xếp. Thay vào đó, hãy sử dụng bản kê khai để thiết lập các tùy chọn tác vụ Activity,
và tạo PendingIntent bằng cách gọi
getActivity():
-
Trong bản kê khai của mình, hãy thêm các thuộc tính sau vào phần tử
<activity>choActivity-
android:name="activityclass" - Tên lớp được xác định đầy đủ của hoạt động.
-
android:taskAffinity="" -
Kết hợp với cờ
FLAG_ACTIVITY_NEW_TASKmà bạn đặt trong mã, điều này đảm bảo rằngActivitynày không đi đến tác vụ mặc định của ứng dụng. Bất kỳ tác vụ hiện tại nào mà có bố trí mặc định của ứng dụng đều không bị ảnh hưởng. -
android:excludeFromRecents="true" - Loại bỏ tác vụ mới khỏi Gần đây, sao cho người dùng không thể vô tình điều hướng quay lại nó.
Đoạn mã HTML này thể hiện phần tử:
<activity android:name=".ResultActivity" ... android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity> ... -
-
Xây dựng và phát hành thông báo:
-
Tạo một
Intentcó chức năng bắt đầuActivity. -
Đặt
Activityđể bắt đầu trong một tác vụ mới, trống bằng cách gọisetFlags()với các cờFLAG_ACTIVITY_NEW_TASKvàFLAG_ACTIVITY_CLEAR_TASK. -
Đặt bất kỳ tùy chọn nào khác mà bạn cần cho
Intent. -
Tạo một
PendingIntenttừIntentbằng cách gọigetActivity(). Sau đó, bạn có thể sử dụngPendingIntentnày làm tham đối tớisetContentIntent().
Đoạn mã HTML sau minh họa tiến trình:
// Instantiate a Builder object. NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // Creates an Intent for the Activity Intent notifyIntent = new Intent(this, ResultActivity.class); // Sets the Activity to start in a new, empty task notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Creates the PendingIntent PendingIntent notifyPendingIntent = PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT ); // Puts the PendingIntent into the notification builder builder.setContentIntent(notifyPendingIntent); // Notifications are issued by sending them to the // NotificationManager system service. NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Builds an anonymous Notification object from the builder, and // passes it to the NotificationManager mNotificationManager.notify(id, builder.build()); -
Tạo một
Hiển thị Tiến độ trong một Thông báo
Thông báo có thể bao gồm một chỉ báo tiến độ dạng hoạt ảnh để cho người dùng thấy trạng thái của một thao tác đang diễn ra. Nếu bạn có thể ước lượng thao tác mất bao lâu và nó được được hoàn thành bao nhiêu vào bất cứ lúc nào, hãy sử dụng hình thức "xác định" của chỉ báo (thanh tiến độ). Nếu bạn không thể ước lượng thời lượng của thao tác, hãy sử dụng hình thức "không xác định" của chỉ báo (chỉ báo hoạt động).
Chỉ báo tiến độ được hiển thị bằng triển khai lớp
ProgressBar của nền tảng.
Để sử dụng chỉ báo tiến độ trên các nền tảng bắt đầu từ Android 4.0, hãy gọi
setProgress(). Đối
với các phiên bản trước đây, bạn phải tạo bố trí thông báo tùy chỉnh của chính mình
trong đó chứa một dạng xem ProgressBar.
Phần sau đây mô tả cách hiển thị tiến độ trong một thông báo bằng cách sử dụng
setProgress().
Hiển thị một chỉ báo tiến độ thời lượng cố định
Để hiển thị một thanh tiến độ xác định, hãy thêm thanh vào thông báo của bạn bằng cách gọi
setProgress(max, progress, false) rồi phát hành thông báo. Khi thông báo của bạn tiến hành,
tăng dầnprogress, và cập nhật thông báo. Khi kết thúc thao tác,
progress sẽ bằng max. Một cách thông thường để gọi
setProgress()
đó là đặt max thành 100 rồi tăng dần progress dưới dạng giá trị
"phần trăm hoàn thành" cho thao tác.
Bạn có thể hoặc để thanh tiến độ hiển thị khi nào thì thao tác hoàn thành, hoặc loại bỏ nó. Dù
trong trường hợp nào hãy nhớ cập nhật văn bản thông báo để hiển thị thao tác hoàn tất.
Để loại bỏ thanh tiến độ, hãy gọi
setProgress(0, 0, false). Ví dụ:
...
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
new Runnable() {
@Override
public void run() {
int incr;
// Do the "lengthy" operation 20 times
for (incr = 0; incr <= 100; incr+=5) {
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
mBuilder.setProgress(100, incr, false);
// Displays the progress bar for the first time.
mNotifyManager.notify(0, mBuilder.build());
// Sleeps the thread, simulating an operation
// that takes time
try {
// Sleep for 5 seconds
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.d(TAG, "sleep failure");
}
}
// When the loop is finished, updates the notification
mBuilder.setContentText("Download complete")
// Removes the progress bar
.setProgress(0,0,false);
mNotifyManager.notify(ID, mBuilder.build());
}
}
// Starts the thread by calling the run() method in its Runnable
).start();
Hiển thị một chỉ báo hoạt động liên tục
Để hiển thị một chỉ báo hoạt động không xác định, hãy thêm nó vào thông báo của bạn bằng
setProgress(0, 0, true)
(hai tham đối đầu tiên bị bỏ qua), và phát hành thông báo. Kết quả là một chỉ báo
mà có cùng kiểu như một thanh tiến độ, khác ở chỗ hoạt ảnh của nó đang diễn ra.
Phát hành thông báo khi bắt đầu thao tác. Hoạt ảnh sẽ chạy tới khi bạn
sửa đổi thông báo của mình. Khi thao tác hoàn thành, hãy gọi
setProgress(0, 0, false)
và rồi cập nhật thông báo để loại bỏ chỉ báo hoạt động.
Luôn làm điều này; nếu không, hoạt ảnh sẽ chạy ngay cả khi thao tác đã hoàn thành. Đồng thời
hãy nhớ thay đổi văn bản thông báo để biểu thị thao tác hoàn tất.
Để xem chỉ báo hoạt động vận hành như thế nào, hãy tham khảo đoạn mã HTML trước. Định vị các dòng sau:
// Sets the progress indicator to a max value, the current completion // percentage, and "determinate" state mBuilder.setProgress(100, incr, false); // Issues the notification mNotifyManager.notify(0, mBuilder.build());
Thay thế các dòng bạn đã tìm thấy bằng các dòng sau:
// Sets an activity indicator for an operation of indeterminate length mBuilder.setProgress(0, 0, true); // Issues the notification mNotifyManager.notify(0, mBuilder.build());
Siêu dữ liệu Thông báo
Thông báo có thể được sắp xếp theo siêu dữ liệu mà bạn gán cho bằng các
phương pháp NotificationCompat.Builder sau:
setCategory()thông báo hệ thống cách xử lý thông báo ứng dụng của bạn khi thiết bị đang trong chế độ Ưu tiên (ví dụ, nếu thông báo của bạn biểu diễn một cuộc gọi đến, tin nhắn tức thời hoặc báo thức).setPriority()khiến thông báo với trường mức ưu tiên được đặt thànhPRIORITY_MAXhoặcPRIORITY_HIGHxuất hiện trong một cửa sổ nổi nhỏ nếu thông báo cũng có âm thanh hoặc rung.addPerson()cho phép bạn thêm một danh sách người vào thông báo. Ứng dụng của bạn có thể sử dụng tín hiệu này cho hệ thống mà nó sẽ nhóm cùng với thông báo từ những người được quy định, hoặc xếp hạng thông báo từ những người này là quan trọng hơn.
Hình 3. Hoạt động toàn màn hình thể hiện một thông báo cảnh báo
Thông báo Cảnh báo
Với Android 5.0 (API mức 21), thông báo có thể xuất hiện trong một cửa sổ nổi nhỏ (còn gọi là thông báo cảnh báo) khi thiết bị hiện hoạt (tức là thiết bị được mở khóa và màn hình của nó đang bật). Những thông báo này có vẻ tương tự như dạng rút gọn thông báo của bạn, chỉ khác là thông báo cảnh báo cũng hiển thị các nút hành động. Người dùng có thể hành động trên đó, hoặc bỏ, một thông báo cảnh báo mà không phải rời khỏi ứng dụng hiện tại.
Các ví dụ về điều kiện có thể kích khởi thông báo cảnh báo bao gồm:
- Hoạt động của người dùng đang trong chế độ toàn màn hình (ứng dụng sử dụng
fullScreenIntent), hoặc - Thông báo có mức ưu tiên cao và sử dụng nhạc chuông hoặc rung
Thông báo Màn hình Khóa
Với việc phát hành Android 5.0 (API mức 21), giờ đây thông báo có thể xuất hiện trên màn hình khóa. Ứng dụng của bạn có thể sử dụng tính năng này để cung cấp các chức năng điều khiển phát lại phương tiện và các hành động thông dụng khác. Người dùng có thể chọn thông qua Cài đặt để xem có hiển thị thông báo trên màn hình khóa không, và bạn có thể chỉ định xem thông báo từ ứng dụng của mình có hiển thị trên màn hình khóa không.
Thiết đặt Khả năng Hiển thị
Ứng dụng của bạn có thể điều khiển mức chi tiết có thể nhìn thấy được trong thông báo được hiển thị trên một
màn hình khóa bảo mật. Bạn gọi setVisibility()
và quy định một trong những giá trị sau:
VISIBILITY_PUBLIChiển thị đầy đủ nội dung của thông báo.VISIBILITY_SECRETkhông hiển thị bất kỳ phần nào của thông báo này trên màn hình khóa.VISIBILITY_PRIVATEhiển thị thông tin cơ bản, chẳng hạn như biểu tượng và tiêu đề nội dung của thông báo, nhưng ẩn nội dung đầy đủ của thông báo.
Khi VISIBILITY_PRIVATE được đặt, bạn cũng có thể
cung cấp một phiên bản thay thế cho nội dung thông báo, trong đó ẩn một số chi tiết nhất định. Ví dụ,
một ứng dụng SMS có thể hiển thị một thông báo hiển thị Bạn có 3 tin nhắn văn bản mới, nhưng ẩn
nội dung của tin nhắn và người gửi. Để 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 cách sử dụng NotificationCompat.Builder. Khi bạn tạo
đối tượng thông báo riêng tư, hãy đính kèm thông báo thay thế cho nó thông qua phương pháp
setPublicVersion()
.
Điều khiển Phát lại Phương tiện trên Màn hình Khóa
Trong Android 5.0 (API mức 21) màn hình khóa không còn hiển thị điều khiển phương tiện
dựa trên RemoteControlClient, điều mà nay đã bị bỏ đi. Thay vào đó, hãy sử dụng mẫu
Notification.MediaStyle với phương pháp
addAction()
, có chức năng chuyển hành động thành các biểu tượng có thể nhấp.
Lưu ý: Mẫu và phương pháp addAction()
không nằm trong thư viện hỗ trợ, vì thế những tính năng này chỉ chạy trong phiên bản Android 5.0 trở lên
.
Để hiển thị điều khiển phát lại phương tiện trên màn hình khóa trong Android 5.0, hãy đặt mức độ nhìn thấy
thành VISIBILITY_PUBLIC, như mô tả bên trên. Sau đó thêm
các hành động và đặt mẫu Notification.MediaStyle, như được mô tả trong
đoạn mã mẫu sau:
Notification notification = new Notification.Builder(context)
// Show controls on lock screen even when user hides sensitive content.
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_stat_player)
// Add media control buttons that invoke intents in your media service
.addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
.addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1
.addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2
// Apply the media style template
.setStyle(new Notification.MediaStyle()
.setShowActionsInCompactView(1 /* #1: pause button */)
.setMediaSession(mMediaSession.getSessionToken())
.setContentTitle("Wonderful music")
.setContentText("My Awesome Band")
.setLargeIcon(albumArtBitmap)
.build();
Lưu ý: Việc rút bỏ RemoteControlClient
còn có nhiều ý nghĩa khác đối với việc điều khiển phương tiện. Xem phần
Điều khiển Phát lại Phương tiện
để biết thêm thông tin về các API mới đối với quản lý phiên phương tiện và điều khiển phát lại này.
Bố trí Thông báo Tùy chỉnh
Khuôn khổ thông báo cho phép bạn định nghĩa một bố trí thông báo tùy chỉnh, nó
định nghĩa hình thức của thông báo trong một đối tượng RemoteViews.
Thông báo có bố trí tùy chỉnh tương tự như thông báo thường, nhưng chúng được dựa trên
RemoteViews được định nghĩa trong một tệp bố trí XML.
Chiều cao sẵn có cho bố trí thông báo tùy chỉnh phụ thuộc vào dạng xem thông báo. Bố trí dạng xem bình thường được giới hạn ở 64 dp, và bố trí dạng xem mở rộng được giới hạn ở 256 dp.
Để định nghĩa một bố trí thông báo tùy chỉnh, hãy bắt đầu bằng việc khởi tạo đối tượng
RemoteViews để bung một tệp bố trí XML. Sau đó,
thay vì gọi các phương pháp như
setContentTitle(),
hãy gọi setContent(). Để đặt
chi tiết nội dung trong thông báo tùy chỉnh, hãy sử dụng các phương pháp
RemoteViews để đặt giá trị của các tập con của dạng xem:
-
Tạo một bố trí XML cho thông báo trong một tệp riêng. Bạn có thể sử dụng bất kỳ tên tệp nào
mà bạn muốn, nhưng phải sử dụng phần mở rộng
.xml -
Trong ứng dụng của bạn, hãy sử dụng các phương pháp
RemoteViewsđể định nghĩa các biểu tượng và văn bản của thông báo của bạn. Đặt đối tượngRemoteViewsnày vàoNotificationCompat.Buildercủa bạn bằng cách gọisetContent(). Tránh đặt mộtDrawablenền trên đối tượngRemoteViewscủa bạn, vì màu văn bản của bạn có thể không đọc được.
Lớp RemoteViews cũng bao gồm các phương pháp mà bạn có thể sử dụng để dễ dạng
thêm một Chronometer hoặc ProgressBar
vào bố trí thông báo của bạn. Để biết thêm thông tin về việc tạo bố trí tùy chỉnh cho thông báo
của mình, hãy tham khảo tài liệu tham khảo RemoteViews.
Chú ý: Khi bạn sử dụng một bố trí thông báo tùy chỉnh, hãy đặc biệt cẩn thận để đảm bảo rằng bố trí tùy chỉnh của bạn có tác dụng với các hướng và độ phân giải thiết bị khác nhau. Trong khi lời khuyên này áp dụng cho tất cả bố trí Dạng xem, nó đặc biệt quan trọng đối với thông báo vì khoảng trống trong ngăn kéo thông báo rất hạn chế. Không được tạo bố trí tùy chỉnh của bạn quá phức tạp và đảm bảo kiểm tra nó trong các cấu hình khác nhau.
Sử dụng các tài nguyên kiểu cho văn bản thông báo tùy chỉnh
Luôn sử dụng tài nguyên kiểu cho văn bản của một thông báo tùy chỉnh. Màu nền của thông báo có thể thay đổi giữa các thiết bị và phiên bản khác nhau, và việc sử dụng tài nguyên kiểu sẽ giúp bạn khắc phục điều này. Bắt đầu từ Android 2.3, hệ thống đã định nghĩa kiểu cho văn bản bố trí thông báo chuẩn. Nếu bạn sử dụng cùng kiểu trong các ứng dụng nhắm đến phiên bản Android 2.3 hoặc cao hơn, bạn sẽ phải đảm bảo rằng văn bản của bạn nhìn thấy được trên nền hiển thị.