Kể từ API Android cấp 26, bạn phải có thông báo liên tục cho các dịch vụ trên nền trước. Yêu cầu này nhằm ngăn bạn ẩn các dịch vụ có thể tạo ra nhu cầu quá mức đối với tài nguyên hệ thống, bao gồm pin nói riêng. Yêu cầu này có thể gây ra một vấn đề tiềm ẩn: Nếu một ứng dụng khi có nhiều dịch vụ trên nền trước không quản lý thông báo một cách cẩn thận, vì vậy, rằng dữ liệu đó được chia sẻ trên tất cả các dịch vụ, do đó có thể có nhiều thông báo không thể bỏ qua, dẫn đến sự lộn xộn không mong muốn trong danh sách đang hoạt động thông báo.
Vấn đề này trở nên khó khăn hơn khi bạn sử dụng các SDK như Điều hướng
SDK chạy các dịch vụ trên nền trước độc lập với ứng dụng có
sở hữu các thông báo ổn định độc lập, khiến cho chúng khó hợp nhất.
Để giải quyết những vấn đề này, SDK điều hướng phiên bản 1.11 đã giới thiệu một API đơn giản để
giúp quản lý các thông báo liên tục trên ứng dụng, kể cả trong SDK.
Thành phần
Trình quản lý dịch vụ trên nền trước cung cấp một trình bao bọc xung quanh nền trước của Android lớp dịch vụ và lớp thông báo liên tục. Trình bao bọc chính của trình bao bọc này là để thực thi việc sử dụng lại ID thông báo để thông báo được chia sẻ trên mọi dịch vụ trên nền trước bằng trình quản lý.
SDK điều hướng chứa các phương thức tĩnh để khởi chạy và lấy phương thức
ForegroundServiceManager
singleton. Chỉ có thể khởi động singleton này
một lần trong vòng đời của SDK điều hướng. Do đó, nếu bạn sử dụng một trong
lệnh gọi khởi chạy (initForegroundServiceManagerMessageAndIntent()
hoặc
initForegroundServiceManagerProvider()
), thì bạn nên bao quanh
khối này bằng một khối try-catch trong trường hợp đường dẫn đó được nhập lại. SDK điều hướng
gửi một ngoại lệ thời gian chạy nếu bạn gọi một trong hai phương thức nhiều lần trừ phi bạn
trước tiên, hãy xoá mọi tham chiếu đến ForegroundServiceManager
rồi gọi
clearForegroundServiceManager()
trước mỗi lệnh gọi tiếp theo.
Bốn tham số của initForegroundServiceManagerMessageAndIntent()
là
application
, notificationId
, defaultMessage
và resumeIntent
. Nếu
ba tham số cuối cùng là rỗng, thì thông báo là tham số chuẩn
Thông báo về SDK điều hướng. Vẫn có thể ẩn nền trước khác
trong ứng dụng sau thông báo này. Tham số notificationId
chỉ định ID thông báo sẽ được sử dụng cho thông báo. Nếu có
rỗng, thì hệ thống sẽ sử dụng một giá trị tuỳ ý. Bạn có thể đặt tuỳ chọn này một cách rõ ràng để xử lý
xung đột với các thông báo khác, chẳng hạn như thông báo từ một SDK khác. Chiến lược phát hành đĩa đơn
defaultMessage
là một chuỗi được hiển thị khi hệ thống không
điều hướng. resumeIntent
là một ý định được kích hoạt khi thông báo
được nhấp vào. Nếu resumeIntent
là rỗng, hãy nhấp vào thông báo
sẽ bị bỏ qua.
Ba tham số của initForegroundServiceManagerProvider()
là
application
, notificationId
và notificationProvider
. Nếu kết quả cuối cùng
hai tham số là rỗng, thì thông báo là SDK điều hướng tiêu chuẩn
. Tham số notificationId
chỉ định mã thông báo
cho thông báo. Nếu giá trị này là rỗng, thì một giá trị tuỳ ý sẽ là
đã sử dụng. Bạn có thể đặt chính sách này một cách rõ ràng để giải quyết xung đột với các
chẳng hạn như các thông báo của một SDK khác. Nếu notificationProvider
là
thì trình cung cấp sẽ luôn chịu trách nhiệm về
bằng cách tạo thông báo cần hiển thị.
Phương thức getForegroundServiceManager()
của SDK điều hướng trả về giá trị
singleton của trình quản lý dịch vụ trên nền trước. Nếu bạn chưa tạo tài khoản nào, thì
thì tương đương với việc gọi initForegroundServiceManagerMessageAndIntent()
có tham số rỗng cho notificationId
, defaultMessage
và
resumeIntent
.
ForegroundServiceManager
có 3 phương thức đơn giản. Hai câu trả lời đầu tiên là dành cho
di chuyển một dịch vụ vào và ra khỏi nền trước, thường được gọi từ
trong dịch vụ đã được tạo. Việc sử dụng các phương pháp này đảm bảo rằng
các dịch vụ khác đều liên kết với thông báo liên tục được chia sẻ. Trận chung kết
phương thức updateNotification()
, gắn cờ trình quản lý mà thông báo đã
đã thay đổi và nên được hiển thị lại.
Nếu bạn cần kiểm soát hoàn toàn thông báo liên tục được chia sẻ, hãy
API này cung cấp giao diện NotificationContentProvider
để xác định
nhà cung cấp thông báo chứa một phương thức duy nhất để nhận thông báo
với nội dung hiện tại. Lớp này cũng cung cấp lớp cơ sở mà bạn có thể
sử dụng (không bắt buộc) để xác định trình cung cấp. Một trong những thành phần chính của lớp cơ sở
là cung cấp cách gọi updateNotification()
mà không cần
cần truy cập vào ForegroundServiceManager
. Nếu bạn sử dụng một phiên bản của
nhà cung cấp thông báo để nhận các tin nhắn thông báo mới, bạn có thể gọi hàm này
nội bộ để hiển thị nội dung trong thông báo.
Trường hợp sử dụng
Phần này trình bày chi tiết các trường hợp sử dụng dữ liệu cố định dùng chung thông báo.
- Ẩn thông báo liên tục về các dịch vụ khác trên nền trước của ứng dụng
- Trường hợp dễ nhất là duy trì hành vi hiện tại và chỉ sử dụng
thông báo liên tục để hiển thị thông tin về SDK điều hướng. Dịch vụ khác
có thể ẩn sau thông báo này bằng cách sử dụng trình quản lý dịch vụ trên nền trước
Phương thức
startForeground()
vàstopForeground()
. - Ẩn thông báo liên tục về các dịch vụ trên nền trước khác của ứng dụng, nhưng đặt văn bản mặc định sẽ xuất hiện khi không đi theo chỉ dẫn
- Tình huống dễ nhất thứ hai là duy trì hành vi hiện tại và chỉ sử dụng
thông báo liên tục để hiển thị thông tin về SDK điều hướng, ngoại trừ
khi hệ thống không điều hướng. Khi hệ thống không điều hướng,
chuỗi được cung cấp cho
initForegroundServiceManagerMessageAndIntent()
được hiển thị thay vì chuỗi SDK điều hướng mặc định đề cập đến "Google Maps". Bạn cũng có thể sử dụng lệnh gọi này để thiết lập ý định tiếp tục kích hoạt khi thông báo được nhấp vào. - Có toàn quyền kiểm soát quá trình hiển thị thông báo liên tục
- Tình huống cuối cùng yêu cầu xác định và tạo trình cung cấp thông báo
và truyền tham số đó đến
ForegroundServiceManager
bằng cách sử dụnginitForegroundServiceManagerProvider()
. Lựa chọn này giúp bạn toàn quyền kiểm soát nội dung hiển thị trong thông báo, mà còn ngắt kết nối thông tin thông báo SDK điều hướng khỏi thông báo, do đó loại bỏ những lời nhắc hữu ích theo từng chặng hiển thị trong . Google không cung cấp một phương thức đơn giản để truy xuất dữ liệu này rồi chèn thông tin đó vào thông báo.
Ví dụ về trình cung cấp thông báo
Ví dụ về mã sau đây minh hoạ cách tạo và trả về thông báo thông qua một trình cung cấp nội dung thông báo đơn giản.
public class NotificationContentProviderImpl
extends NotificationContentProviderBase
implements NotificationContentProvider {
private String channelId;
private Context context;
private String message;
/** Constructor */
public NotificationContentProviderImpl(Application application) {
super(application);
message = "-- uninitialized --";
channelId = null;
this.context = application;
}
/**
* Sets message to display in the notification. Calls updateNotification
* to display the message immediately.
*
* @param msg The message to display in the notification.
*/
public void setMessage(String msg) {
message = msg;
updateNotification();
}
/**
* Returns the notification as it should be rendered.
*/
@Override
public Notification getNotification() {
Notification notification;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Spanned styledText = Html.fromHtml(message, FROM_HTML_MODE_LEGACY);
String channelId = getChannelId(context);
notification =
new Notification.Builder(context, channelId)
.setContentTitle("Notifications Demo")
.setStyle(new Notification.BigTextStyle()
.bigText(styledText))
.setSmallIcon(R.drawable.ic_navigation_white_24dp)
.setTicker("ticker text")
.build();
} else {
notification = new Notification.Builder(context)
.setContentTitle("Notification Demo")
.setContentText("testing non-O text")
.build();
}
return notification;
}
// Helper to set up a channel ID.
private String getChannelId(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (channelId == null) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(
"default", "navigation", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("For navigation persistent notification.");
notificationManager.createNotificationChannel(channel);
channelId = channel.getId();
}
return channelId;
} else {
return "";
}
}
}
Sau khi tạo NotificationContentProviderImpl
, bạn kết nối với
SDK điều hướng vào đó bằng cách sử dụng mã sau:
ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);
Cảnh báo và kế hoạch trong tương lai
- Hãy nhớ gọi
initForegroundServiceManagerMessageAndIntent()
hoặcinitForegroundServiceManagerProvider()
sớm để kịch bản sử dụng dự kiến đã được xác định rõ. Bạn phải gọi phương thức này trước khi bạn tạo một Trình điều hướng mới. - Hãy nhớ phát hiện các ngoại lệ từ các lệnh gọi đến
initForegroundServiceManagerMessageAndIntent()
hoặcinitForegroundServiceManagerProvider()
trong trường hợp lộ trình mã là được nhập nhiều lần. Trong SDK điều hướng phiên bản 2.0, hãy gọi phương thức này nhiều lần sẽ gửi một ngoại lệ đã đánh dấu thay vì ngoại lệ trong thời gian chạy. - Có thể Google vẫn còn việc cần làm để tạo kiểu nhất quán cho thời gian tồn tại của thông báo khớp với kiểu tiêu đề.
- Khi xác định nhà cung cấp thông báo, bạn có thể kiểm soát hành vi quan trọng với mức độ ưu tiên.
- Google không cung cấp một phương tiện đơn giản để truy xuất từng chặng thông tin mà nhà cung cấp thông báo có thể chèn vào thông báo.