Theo mặc định, tính năng lên lịch chuông báo chính xác bị từ chối

Chuông báo chính xác là tính năng dành cho các thông báo mà người dùng có ý định thực hiện, hoặc hành động cần thực hiện tại một thời điểm chính xác.

SCHEDULE_EXACT_ALARM, quyền này ra mắt trong Android 12 để các ứng dụng lên lịch báo thức chính xác, không còn được cấp trước cho hầu hết ứng dụng mới cài đặt nhắm đến Android 13 trở lên (sẽ được thiết lập thành bị từ chối theo mặc định). Nếu người dùng chuyển dữ liệu ứng dụng sang một thiết bị chạy Android 14 thông qua tác vụ sao lưu và khôi phục, thì quyền vẫn sẽ bị từ chối. Nếu một ứng dụng hiện có đã có quyền này, ứng dụng sẽ được cấp trước khi thiết bị nâng cấp lên Android 14.

Cần có quyền SCHEDULE_EXACT_ALARM để kích hoạt chuông báo chính xác thông qua các API sau, nếu không, SecurityException sẽ được gửi:

Các phương pháp hay nhất hiện có đối với quyền SCHEDULE_EXACT_ALARM vẫn áp dụng, bao gồm:

Các ứng dụng bị ảnh hưởng

Nếu thiết bị đang chạy Android 14 trở lên, thay đổi này sẽ ảnh hưởng đến một ứng dụng mới cài đặt có các đặc điểm sau:

Ứng dụng lịch và đồng hồ báo thức phải khai báo USE_EXACT_ALARM

Ứng dụng lịch hoặc đồng hồ báo thức cần phải gửi lời nhắc trên lịch, chuông báo thức hoặc cảnh báo khi không còn chạy nữa. Các ứng dụng này có thể yêu cầu quyền USE_EXACT_ALARM thông thường. Quyền USE_EXACT_ALARM sẽ được cấp khi cài đặt, và các ứng dụng có quyền này sẽ có thể lên lịch chuông báo chính xác giống như các ứng dụng có quyền SCHEDULE_EXACT_ALARM.

Các trường hợp sử dụng có thể không cần đến chuông báo chính xác

Quyền SCHEDULE_EXACT_ALARM hiện bị từ chối theo mặc định và quy trình cấp quyền yêu cầu người dùng thực hiện thêm một số bước, do đó, các nhà phát triển nên đánh giá các trường hợp sử dụng của mình và xác định xem liệu tính năng chuông báo chính xác có thực sự có ý nghĩa đối với trường hợp sử dụng hay không.

Danh sách sau đây cho thấy những quy trình công việc thường gặp có thể không cần đến chuông báo chính xác:

Lên lịch cho công việc lặp lại trong suốt vòng đời của ứng dụng
Phương thức set() sẽ rất hữu ích nếu bạn cần lưu ý các hạn chế theo thời gian thực, chẳng hạn như sẽ tắt lúc 2 giờ chiều mai hoặc 30 phút nữa. Nếu không, bạn nên dùng phương thức postAtTime() hoặc postDelayed().
Thao tác ở chế độ nền đã lên lịch, chẳng hạn như cập nhật ứng dụng và tải nhật ký lên
WorkManager cung cấp cách lập lịch công việc định kỳ có giới hạn thời gian. Bạn có thể cung cấp một khoảng thời gian lặp lại và flexInterval (tối thiểu 15 phút) để xác định thời gian chạy chi tiết cho công việc.
Cần tắt chuông báo vào khoảng thời gian gần đúng khi hệ thống ở trạng thái rảnh
Sử dụng chuông báo không chính xác. Cụ thể, hãy gọi setAndAllowWhileIdle().
Hành động do người dùng chỉ định sẽ xảy ra sau một thời gian cụ thể
Sử dụng chuông báo không chính xác. Cụ thể, hãy gọi set().
Hành động do người dùng chỉ định có thể xảy ra trong một khoảng thời gian
Sử dụng chuông báo không chính xác. Cụ thể, hãy gọi setWindow(). Lưu ý rằng thời lượng nhỏ nhất được cho phép là 10 phút.

Các bước di chuyển để tiếp tục sử dụng chuông báo chính xác

Ít nhất, các ứng dụng phải kiểm tra xem có quyền hay không trước khi lên lịch chuông báo chính xác. Nếu không có quyền, ứng dụng phải yêu cầu quyền đó từ người dùng bằng cách gọi ý định.

Quy trình này giống với quy trình làm việc tiêu chuẩn để yêu cầu một quyền đặc biệt:

  1. Các ứng dụng nên gọi AlarmManager.canScheduleExactAlarms() để xác nhận việc có quyền thích hợp.
  2. Nếu ứng dụng không có quyền này, hãy gọi một ý định bao gồm ACTION_REQUEST_SCHEDULE_EXACT_ALARM cùng với tên gói của ứng dụng để yêu cầu người dùng cấp quyền.

    Kiểm tra quyết định của người dùng trong phương thức onResume() của ứng dụng.

  3. Theo dõi thông báo AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED sẽ được gửi nếu người dùng cấp quyền.

  4. Nếu người dùng đã cấp quyền cho ứng dụng, thì ứng dụng của bạn có thể thiết lập chuông báo chính xác. Thay vào đó, nếu người dùng từ chối cấp quyền, hãy xuống cấp nhẹ cho trải nghiệm ứng dụng của bạn để cung cấp chức năng cho người dùng khi không có thông tin được bảo vệ bằng quyền đó.

Đoạn mã sau đây minh hoạ cách kiểm tra quyền SCHEDULE_EXACT_ALARM:

val alarmManager: AlarmManager = context.getSystemService<AlarmManager>()!!
when {
   // If permission is granted, proceed with scheduling exact alarms.
   alarmManager.canScheduleExactAlarms() -> {
       alarmManager.setExact(...)
   }
   else -> {
       // Ask users to go to exact alarm page in system settings.
       startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
   }
}

Mã mẫu để kiểm tra quyền và xử lý quyết định của người dùng trong onResume():

override fun onResume() {
     
   if (alarmManager.canScheduleExactAlarms()) {
       // Set exact alarms.
       alarmManager.setExact(...)
   }
   else {
       // Permission not yet approved. Display user notice and revert to a fallback  
       // approach.
       alarmManager.setWindow(...)
   }
}

Hãy xuống cấp nhẹ khi từ chối cấp quyền

Một số người dùng sẽ từ chối cấp quyền. Trong trường hợp này, ứng dụng nên xuống cấp nhẹ trải nghiệm một cách linh hoạt và vẫn cố gắng cung cấp trải nghiệm người dùng dự phòng tốt nhất có thể bằng cách xác định các trường hợp sử dụng của người dùng.

Miễn trừ

Các loại ứng dụng sau luôn được phép gọi phương thức setExact() hoặc setExactAndAllowWhileIdle():

  • Ứng dụng ký bằng chứng chỉ nền tảng.
  • Ứng dụng ưu tiên.
  • Các ứng dụng nằm trong danh sách cho phép sử dụng nguồn pin (nếu ứng dụng của bạn phù hợp với các yêu cầu này, bạn có thể yêu cầu điều này bằng cách sử dụng thao tác theo ý định ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).

Cấp quyền trước

  • Ứng dụng giữ vai trò SYSTEM_WELLBEING sẽ được cấp trước quyền SCHEDULE_EXACT_ALARM.

Nguyên tắc kiểm thử

Để kiểm tra thay đổi này, hãy tắt quyền Chuông báo và lời nhắc cho ứng dụng của bạn từ trang Quyền truy cập ứng dụng đặc biệt trong phần Cài đặt hệ thống (Cài đặt > Ứng dụng > Quyền truy cập ứng dụng đặc biệt > Chuông báo và lời nhắc), đồng thời quan sát hành vi của ứng dụng.