Hạn chế khi bắt đầu hoạt động ở chế độ nền

Android 10 (cấp độ API 29) trở lên đặt ra các hạn chế về thời điểm ứng dụng có thể bắt đầu hoạt động khi chạy ở chế độ nền. Những hạn chế này giúp giảm thiểu sự gián đoạn cho người dùng và giúp người dùng kiểm soát tốt hơn nội dung hiển thị trên màn hình.

Hướng dẫn này trình bày thông báo như một giải pháp thay thế để bắt đầu hoạt động ở chế độ nền. Hướng dẫn này cũng liệt kê các trường hợp cụ thể mà hạn chế không áp dụng.

Hiển thị thông báo thay vì bắt đầu hoạt động

Trong hầu hết mọi trường hợp, các ứng dụng ở chế độ nền phải hiển thị thông báo nhạy cảm về thời gian để cung cấp thông tin khẩn cấp cho người dùng thay vì trực tiếp bắt đầu một hoạt động. Các thông báo như vậy bao gồm xử lý cuộc gọi điện thoại đến hoặc đồng hồ báo thức đang hoạt động.

Hệ thống cảnh báo và nhắc nhở dựa trên thông báo này mang lại một số lợi ích cho người dùng:

  • Khi sử dụng thiết bị, người dùng sẽ thấy một thông báo quan trọng cho phép họ phản hồi. Người dùng vẫn duy trì bối cảnh hiện tại và có quyền kiểm soát nội dung mà họ thấy trên màn hình.
  • Thông báo nhạy cảm về thời gian tuân thủ các quy tắc Không làm phiền của người dùng. Ví dụ: người dùng có thể chỉ cho phép nhận cuộc gọi từ những người liên hệ cụ thể hoặc từ những người gọi lại khi bật chế độ Không làm phiền.
  • Khi màn hình của thiết bị tắt, ý định toàn màn hình sẽ khởi chạy ngay lập tức.
  • Trên màn hình Cài đặt của thiết bị, người dùng có thể thấy những ứng dụng đã gửi thông báo gần đây, kể cả từ các kênh thông báo cụ thể. Trên màn hình này, người dùng có thể kiểm soát lựa chọn ưu tiên về thông báo.

Khi ứng dụng có thể bắt đầu hoạt động

Các ứng dụng chạy trên Android 10 trở lên có thể bắt đầu hoạt động khi đáp ứng một hoặc nhiều điều kiện sau:

  • Ứng dụng có một cửa sổ hiển thị, chẳng hạn như một hoạt động ở nền trước.

  • Ứng dụng có một hoạt động trong ngăn xếp lui của tác vụ trên nền trước.

  • Ứng dụng có một hoạt động trong ngăn xếp lui của một tác vụ hiện có trên màn hình Gần đây.

  • Ứng dụng có một hoạt động đã bắt đầu rất gần đây.

  • Ứng dụng đã gọi finish() trên một hoạt động rất gần đây. Điều này chỉ áp dụng khi ứng dụng có một hoạt động ở nền trước hoặc một hoạt động trong ngăn xếp lui của tác vụ trên nền trước tại thời điểm finish() được gọi.

  • Ứng dụng có một trong các dịch vụ sau đây do hệ thống ràng buộc. Các dịch vụ này có thể cần khởi chạy giao diện người dùng.

  • Ứng dụng có một dịch vụ do một ứng dụng khác đang hiển thị ràng buộc. Ứng dụng được ràng buộc với dịch vụ phải luôn hiển thị để ứng dụng ở chế độ nền có thể bắt đầu hoạt động thành công.

  • Ứng dụng nhận được thông báo PendingIntent từ hệ thống. Trong trường hợp ý định đang chờ xử lý đối với các dịch vụ và bộ nhận tín hiệu truyền tin, ứng dụng có thể bắt đầu hoạt động trong vài giây sau khi ý định đang chờ xử lý được gửi.

  • Ứng dụng nhận được một PendingIntent được gửi từ một ứng dụng khác đang hiển thị.

  • Ứng dụng nhận được một tin do hệ thống truyền ra mà ứng dụng dự kiến sẽ khởi chạy giao diện người dùng. Ví dụ: ACTION_NEW_OUTGOING_CALLSECRET_CODE_ACTION. Ứng dụng có thể bắt đầu hoạt động trong vài giây sau khi tín hiệu truyền tin được gửi.

  • Ứng dụng được liên kết với một thiết bị phần cứng đồng hành thông qua API CompanionDeviceManager. API này cho phép ứng dụng bắt đầu hoạt động để phản hồi các hành động mà người dùng thực hiện trên một thiết bị đã ghép nối.

  • Ứng dụng là một trình kiểm soát chính sách thiết bị chạy ở chế độ chủ sở hữu thiết bị. Các trường hợp sử dụng ví dụ bao gồm thiết bị doanh nghiệp được quản lý hoàn toàn cũng như các thiết bị chuyên dụng như bảng hiệu kỹ thuật số và ki-ốt.

  • Người dùng cấp quyền SYSTEM_ALERT_WINDOW cho ứng dụng.

Bắt buộc chọn sử dụng khi bắt đầu hoạt động từ PendingIntent

Để tránh cho phép bắt đầu Hoạt động do vô tình dựa trên các điều kiện được liệt kê, kể từ Android 14, có các API rõ ràng cho phép bạn chọn sử dụng hoặc không sử dụng việc cấp quyền cho ứng dụng để bắt đầu Hoạt động.

Các ứng dụng nhắm đến Android 15 trở lên sẽ mặc định không còn ngầm cấp đặc quyền khởi chạy hoạt động ở chế độ nền (BAL) cho PendingIntents mà chúng tạo. Bạn phải chọn sử dụng rõ ràng để thực hiện việc này. Sau đây là các lựa chọn tuỳ thuộc vào việc ứng dụng đang gửi hay tạo PendingIntents.

Bảng ý định đang chờ xử lý
Hình 1: Quy trình quyết định cho các lượt khởi chạy hoạt động ở chế độ nền.

Theo Người gửi PendingIntent

Các ứng dụng nhắm đến Android 14 trở lên muốn bắt đầu một PendingIntent phải

  • đáp ứng các điều kiện được liệt kê
  • chọn sử dụng để cho phép khởi chạy hoạt động ở chế độ nền dựa trên những trường hợp ngoại lệ đó

Bạn chỉ nên chọn sử dụng tính năng này nếu nhà phát triển ứng dụng biết rằng ứng dụng sẽ bắt đầu một Hoạt động.

Để chọn sử dụng, ứng dụng phải truyền một gói ActivityOptionssetPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) đến PendingIntent.send() hoặc các phương thức tương tự.

Theo Người tạo PendingIntent

Các ứng dụng nhắm đến Android 15 trở lên tạo một PendingIntent hiện phải chọn sử dụng rõ ràng để cho phép khởi chạy hoạt động ở chế độ nền nếu muốn các PendingIntents đó có thể bắt đầu trong các điều kiện được liệt kê.

Trong hầu hết các trường hợp, ứng dụng bắt đầu PendingIntent phải là ứng dụng chọn sử dụng. Tuy nhiên, nếu ứng dụng tạo cần cấp các đặc quyền này:

  • PendingIntent có thể bắt đầu bất cứ lúc nào ứng dụng tạo hiển thị.
  • PendingIntent có thể bắt đầu bất cứ lúc nào nếu ứng dụng tạo có các đặc quyền đặc biệt.

Để chọn sử dụng, ứng dụng phải truyền một gói ActivityOptionssetPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) đến PendingIntent.getActivity() hoặc các phương thức tương tự.

Đọc tài liệu tham khảo có liên quan để biết thêm thông tin chi tiết:

Chế độ nghiêm ngặt

Kể từ Android 16, nhà phát triển ứng dụng có thể bật Chế độ nghiêm ngặt để nhận thông báo khi một lượt khởi chạy hoạt động bị chặn (hoặc có nguy cơ bị chặn khi SDK mục tiêu của ứng dụng được nâng cấp).

Mã ví dụ để bật từ sớm trong phương thức Application.onCreate() của Ứng dụng, Hoạt động hoặc thành phần ứng dụng khác:

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     StrictMode.setVmPolicy(
         StrictMode.VmPolicy.Builder()
         .detectBlockedBackgroundActivityLaunch()
         .penaltyLog()
         .build());
     )
 }

Đọc tài liệu về Chế độ nghiêm ngặt để biết thêm thông tin chi tiết.