Thông báo cục bộ là một tin nhắn mà ứng dụng gửi đến người dùng mà không cần sự tham gia của máy chủ từ xa. Tất cả dữ liệu được xử lý và hiển thị trực tiếp trên thiết bị của người nhận. Cơ chế này phù hợp cho lời nhắc, bộ đếm thời gian và báo thức khi ứng dụng ở chế độ nền hoặc bị đóng. Theo Tài liệu dành cho nhà phát triển Apple, UNUserNotificationCenter cung cấp khả năng quản lý tập trung các thông báo cục bộ trên iOS.
Những điểm chính
Thông báo cục bộ là một tin nhắn kích hoạt được hệ điều hành tạo và hiển thị trên cùng một thiết bị nơi ứng dụng được cài đặt. Không giống như thông báo đẩy, thông báo cục bộ không đi qua máy chủ bên ngoài — tất cả logic lên lịch đều chạy trên máy khách.
Các thông báo này hoạt động bất kể trạng thái của ứng dụng: đang hoạt động, thu nhỏ hoặc đã đóng hoàn toàn. Hệ điều hành đảm nhận việc gửi vào thời gian đã lên lịch, trong khi nhà phát triển chỉ chỉ định nội dung và bộ kích hoạt.
Hệ thống đảm bảo gửi thông báo cục bộ ngay cả khi không có kết nối mạng. Đây là lợi thế chính so với thông báo đẩy, vốn yêu cầu kết nối Internet ổn định và máy chủ hoạt động.
Mỗi thông báo cục bộ bao gồm ba phần: nội dung (tiêu đề, nội dung, âm thanh), bộ kích hoạt (điều kiện thời gian hoặc địa lý) và mã định danh yêu cầu. Mã định danh cho phép hủy hoặc cập nhật thông báo trước khi gửi.
Nhà phát triển có thể lên lịch tối đa 64 thông báo cục bộ cho mỗi ứng dụng trên iOS và số lượng không giới hạn trên Android. Sự khác biệt này là do các ràng buộc về kiến trúc của hệ điều hành.
Cả hai nền tảng đều cung cấp API riêng để làm việc với thông báo cục bộ. Trên iOS, thành phần trung tâm là UNUserNotificationCenter, trên Android — NotificationManager. Mặc dù giao diện khác nhau, logic là giống nhau: ứng dụng tạo yêu cầu, đăng ký với hệ thống và hệ điều hành gửi thông báo vào thời gian đã lên lịch.
iOS sử dụng UNCalendarNotificationTrigger cho sự kiện lịch, UNTimeIntervalNotificationTrigger cho khoảng thời gian và UNLocationNotificationTrigger cho vị trí địa lý. Android cung cấp AlarmManager, WorkManager và lên lịch chính xác qua setExact.
Từ Android 12 — SCHEDULE_EXACT_ALARM yêu cầu quyền đặc biệt từ người dùng. Trên iOS, quyền được yêu cầu một lần qua UNUserNotificationCenter.requestAuthorization và người dùng chọn mức truy cập: banner, âm thanh, huy hiệu.
Thông báo cục bộ được phân loại theo loại bộ kích hoạt, không phải theo nội dung. Mỗi loại xác định khi nào và trong điều kiện nào thông báo sẽ được hiển thị cho người dùng.
Trên iOS và Android, các loại bộ kích hoạt được triển khai khác nhau, mặc dù phân loại logic là giống nhau. iOS sử dụng UNCalendarNotificationTrigger cho ngày tháng, UNTimeIntervalNotificationTrigger cho khoảng thời gian và UNLocationNotificationTrigger cho vị trí địa lý. Android cung cấp AlarmManager với setExact và setRepeating, cũng như WorkManager cho các tác vụ trì hoãn.
| Loại bộ kích hoạt | Mô tả | Ví dụ |
|---|---|---|
| Khoảng thời gian | Thông báo sau N giây kể từ khi khởi động | Đếm ngược thời gian |
| Ngày lịch | Thông báo vào thời gian và ngày cụ thể | Lời nhắc cuộc họp |
| Vị trí địa lý | Thông báo khi vào/rời khỏi khu vực | Lời nhắc tại cửa hàng |
| Tức thì | Gửi ngay lập tức khi gọi API | Thông báo tải xuống |
iOS cũng hỗ trợ UNNotificationAttachment — đính kèm hình ảnh, âm thanh hoặc video vào nội dung thông báo. Android hỗ trợ các mẫu tùy chỉnh với nút bấm và hình ảnh lớn qua NotificationCompat.Style.
Việc chọn bộ kích hoạt phụ thuộc vào tình huống: lời nhắc lịch hoạt động tốt nhất với bộ kích hoạt lịch, lời nhắc địa lý với vị trí địa lý. Bộ kích hoạt khoảng thời gian phù hợp cho các sự kiện định kỳ với khoảng thời gian cố định.
Trên iOS, thông báo cục bộ được hệ thống gửi ngay cả khi ứng dụng bị đóng — UNUserNotificationCenter quản lý hàng đợi độc lập. Trên Android, việc gửi phụ thuộc vào cơ chế đã chọn: AlarmManager kích hoạt ngay cả khi màn hình tắt, trong khi WorkManager tính đến việc tiết kiệm pin.
Thông báo cục bộ giải quyết các tác vụ mà cơ sở hạ tầng bên ngoài là quá mức hoặc không khả dụng. Các tình huống chính: lời nhắc, bộ đếm thời gian, mẹo hướng dẫn và hành động trì hoãn.
Nghiên cứu của Localytics cho thấy các ứng dụng sử dụng lời nhắc cục bộ giữ chân được nhiều hơn 35% người dùng trong tuần đầu tiên sau khi cài đặt. Điều này làm cho thông báo cục bộ trở thành công cụ hướng dẫn mạnh mẽ.
Điều quan trọng là không lạm dụng tần suất — hệ thống tự động nhóm các thông báo từ cùng một ứng dụng và người dùng có thể tắt tất cả thông báo cục bộ nếu chúng gây khó chịu. Tần suất tối ưu là không quá 2–3 thông báo mỗi ngày cho các sự kiện không quan trọng.
Để lên lịch thông báo cục bộ trên Android, hãy sử dụng NotificationManager cùng với AlarmManager. Trên Android 8+, trước tiên bạn phải tạo kênh thông báo, nếu không thông báo sẽ không hiển thị.
val channelId = "reminder_channel"
val notificationId = "task_reminder_42"
val channel = NotificationChannel(
channelId,
"Lời nhắc",
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "Kênh cho lời nhắc tác vụ"
}
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
val intent = Intent(this, ReminderReceiver::class.java).apply {
putExtra("notification_id", notificationId)
putExtra("channel_id", channelId)
}
val pendingIntent = PendingIntent.getBroadcast(
this, notificationId.hashCode(),
intent, PendingIntent.FLAG_UPDATE_CURRENT
)
val alarmManager = getSystemService(AlarmManager::class.java)
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMillis,
pendingIntent
)
Trên Android 12+, hãy kiểm tra quyền SCHEDULE_EXACT_ALARM trước khi gọi setExact. Nếu quyền không được cấp — hãy sử dụng setWindow, đảm bảo gửi trong một khung thời gian.
Khi AlarmManager kích hoạt, hệ thống gửi một Intent quảng bá được BroadcastReceiver nhận. Bên trong nó, bạn cần tạo và hiển thị thông báo qua NotificationManager. Đảm bảo rằng PendingIntent sử dụng FLAG_UPDATE_CURRENT, nếu không các thông báo cũ sẽ tiếp tục sử dụng Intent lỗi thời khi dữ liệu thay đổi.
Trên iOS, thông báo cục bộ được tạo qua UNUserNotificationCenter bằng UNMutableNotificationContent và một trong các bộ kích hoạt. Trước khi lên lịch, bạn phải xin phép người dùng.
import UserNotifications
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
guard granted else { return }
}
let content = UNMutableNotificationContent()
content.title = "Lời nhắc tác vụ"
content.body = "Đừng quên hoàn thành báo cáo trước 18:00"
content.sound = .default
content.userInfo = ["task_id": "42"]
let trigger = UNTimeIntervalNotificationTrigger(
timeInterval: 3600,
repeats: false
)
let request = UNNotificationRequest(
identifier: "task_reminder_42",
content: content,
trigger: trigger
)
center.add(request)
iOS hỗ trợ tối đa 64 yêu cầu thông báo cục bộ đồng thời. Nếu vượt quá giới hạn, hệ thống từ chối các yêu cầu mới cho đến khi các yêu cầu đang hoạt động được gửi hoặc hủy. Sử dụng getPendingNotificationRequests để kiểm tra hàng đợi hiện tại.
Khi người dùng tương tác với thông báo cục bộ trên iOS, phương thức userNotificationCenter:didReceive response của delegate UNUserNotificationCenterDelegate được gọi. Phương thức này cung cấp mã định danh yêu cầu, actionIdentifier (nút nào được nhấn) và userInfo tùy chỉnh. Điều này cho phép phân biệt giữa việc mở thông báo đơn giản và nhấn nút hành động cụ thể.
Để thông báo cục bộ hữu ích thay vì gây khó chịu, hãy tuân theo một số quy tắc chính. Thứ nhất: kiểm soát tần suất — không quá 2–3 thông báo mỗi ngày cho các sự kiện không quan trọng, nếu không người dùng sẽ tắt tất cả thông báo của ứng dụng.
Thứ hai: cho người dùng lựa chọn. Thêm vào giao diện khả năng tắt một số loại thông báo cục bộ. Trên Android, sử dụng NotificationChannel riêng với mức độ quan trọng thấp; trên iOS, sử dụng danh mục riêng trong cài đặt ứng dụng.
Thứ ba: sự phù hợp theo ngữ cảnh — thông báo sẽ xuất hiện khi người dùng cần. Bộ kích hoạt địa lý lý tưởng cho lời nhắc gần nhà, bộ kích hoạt lịch cho cuộc họp, bộ kích hoạt khoảng thời gian cho các hoạt động thường xuyên như uống nước hoặc giãn cơ. Đừng trộn lẫn các loại một cách không cần thiết.
Thứ tư: kiểm tra trên thiết bị thực. Trình mô phỏng iOS không mô phỏng tất cả các tình huống gửi thông báo cục bộ, đặc biệt là trong nền. Trên Android, sử dụng adb shell dumpsys notification để kiểm tra hàng đợi thông báo đã lên lịch và tham số của chúng. Thứ năm: luôn cung cấp cho người dùng khả năng tắt thông báo qua giao diện ứng dụng — đây là yêu cầu bắt buộc của UX và Nguyên tắc đánh giá App Store.
Câu hỏi thường gặp
Thông báo cục bộ được lên lịch và gửi bởi thiết bị mà không cần sự tham gia của máy chủ. Thông báo đẩy yêu cầu dịch vụ bên ngoài (FCM, APNS) và kết nối Internet. Thông báo cục bộ hoạt động ngoại tuyến, thông báo đẩy chỉ hoạt động khi có mạng.
iOS giới hạn 64 yêu cầu đã lên lịch đồng thời. Android không có giới hạn nghiêm ngặt, nhưng hơn 500 thông báo có thể làm giảm hiệu suất hệ thống và ảnh hưởng đến thời gian gửi.
Có, trên iOS sử dụng removePendingNotificationRequests với mã định danh yêu cầu. Trên Android, gọi NotificationManager.cancel hoặc hủy PendingIntent qua AlarmManager. Mã định danh duy nhất là bắt buộc để hủy.
Trên iOS, quyền là bắt buộc qua requestAuthorization. Trên Android 13+ (Tiramisu), cũng yêu cầu quyền POST_NOTIFICATIONS. Các phiên bản Android cũ hơn không yêu cầu quyền rõ ràng cho thông báo cục bộ.
Trên iOS, tạo UNNotificationAction và thêm vào UNNotificationCategory. Trên Android, sử dụng NotificationCompat.Builder.addAction với PendingIntent hướng đến BroadcastReceiver. Mỗi nút kích hoạt một hành động riêng biệt trong ứng dụng.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm