Các ứng dụng nhắm đến Android 12 (API cấp 31) trở lên không thể bắt đầu các dịch vụ trên nền trước trong khi ứng dụng đang chạy ở chế độ nền, ngoại trừ một số trường hợp đặc biệt. Nếu một ứng dụng cố gắng khởi động một dịch vụ trên nền trước trong khi ứng dụng chạy ở chế độ nền và dịch vụ trên nền trước không đáp ứng một trong các trường hợp ngoại lệ, thì hệ thống sẽ gửi một ForegroundServiceStartNotAllowedException
.
Ngoài ra, nếu muốn chạy một dịch vụ trên nền trước cần có quyền khi đang sử dụng (ví dụ: quyền truy cập vào cảm biến cơ thể, máy ảnh, micrô hoặc vị trí), thì ứng dụng không thể tạo dịch vụ đó khi đang chạy ở chế độ nền, ngay cả khi ứng dụng thuộc một trong các trường hợp được miễn trừ khỏi các hạn chế khi khởi động ở chế độ nền. Lý do cho việc này được giải thích trong phần Các hạn chế khi bắt đầu dịch vụ trên nền trước cần có quyền sử dụng khi đang dùng.
Các trường hợp được miễn quy định hạn chế về việc khởi động ở chế độ nền
Trong những trường hợp sau, ứng dụng của bạn có thể bắt đầu các dịch vụ trên nền trước ngay cả khi ứng dụng đang chạy ở chế độ nền:
- Ứng dụng của bạn chuyển đổi từ trạng thái mà người dùng có thể thấy, chẳng hạn như một hoạt động.
- Ứng dụng của bạn có thể bắt đầu một hoạt động ở chế độ nền, ngoại trừ trường hợp ứng dụng có một hoạt động trong ngăn xếp lùi của một tác vụ hiện có.
Ứng dụng của bạn nhận được một thông báo có mức độ ưu tiên cao bằng cách sử dụng Giải pháp gửi thông báo qua đám mây của Firebase.
Người dùng thực hiện một thao tác trên một phần tử giao diện người dùng liên quan đến ứng dụng của bạn. Ví dụ: họ có thể tương tác với một bong bóng, thông báo, tiện ích hoặc hoạt động.
Ứng dụng của bạn gọi một chuông báo chính xác để hoàn tất một hành động mà người dùng yêu cầu.
Ứng dụng của bạn là phương thức nhập hiện tại của thiết bị.
Ứng dụng của bạn nhận được một sự kiện liên quan đến hàng rào địa lý hoặc quá trình chuyển đổi nhận dạng hoạt động.
Sau khi thiết bị khởi động lại và nhận được
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
hoặc thao tác theo ý địnhACTION_MY_PACKAGE_REPLACED
trong broadcast receiver.Ứng dụng của bạn nhận được thao tác theo ý định
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
hoặcACTION_LOCALE_CHANGED
trong một broadcast receiver.Ứng dụng của bạn nhận được sự kiện
ACTION_TRANSACTION_DETECTED
từNfcService
.Các ứng dụng có một số vai trò hoặc quyền nhất định của hệ thống, chẳng hạn như chủ sở hữu thiết bị và chủ sở hữu hồ sơ.
Ứng dụng của bạn sử dụng Trình quản lý thiết bị đồng hành và khai báo quyền
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
hoặc quyềnREQUEST_COMPANION_RUN_IN_BACKGROUND
. Nếu có thể, hãy dùngREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
.Người dùng tắt chế độ tối ưu hoá pin cho ứng dụng của bạn.
Ứng dụng của bạn có quyền
SYSTEM_ALERT_WINDOW
. Lưu ý: Nếu ứng dụng của bạn nhắm đến Android 15 trở lên, thì ứng dụng đó phải có quyềnSYSTEM_ALERT_WINDOW
và ứng dụng hiện phải có một cửa sổ lớp phủ hiển thị.
Các hạn chế khi bắt đầu dịch vụ trên nền trước cần có quyền truy cập khi đang sử dụng
Trên Android 14 (API cấp 34) trở lên, bạn cần lưu ý đến một số trường hợp đặc biệt nếu đang bắt đầu một dịch vụ trên nền trước cần có quyền sử dụng khi đang dùng.
Nếu ứng dụng của bạn nhắm đến Android 14 trở lên, thì hệ điều hành sẽ kiểm tra khi bạn tạo một dịch vụ trên nền trước để đảm bảo ứng dụng của bạn có tất cả các quyền phù hợp cho loại dịch vụ đó. Ví dụ: khi bạn tạo một dịch vụ trên nền trước thuộc loại microphone, hệ điều hành sẽ xác minh rằng ứng dụng của bạn hiện có quyền RECORD_AUDIO
. Nếu bạn không có quyền đó, hệ thống sẽ gửi ra một SecurityException
.
Đối với quyền khi đang sử dụng, điều này có thể gây ra vấn đề. Nếu có quyền truy cập khi ở nền trước, thì ứng dụng của bạn chỉ có quyền đó khi ở nền trước. Điều này có nghĩa là nếu ứng dụng của bạn ở chế độ nền và cố gắng tạo một dịch vụ trên nền trước thuộc loại camera, vị trí hoặc micrô, thì hệ thống sẽ nhận thấy rằng ứng dụng của bạn hiện không có các quyền cần thiết và hệ thống sẽ gửi một SecurityException
.
Tương tự, nếu ứng dụng của bạn ở chế độ nền và tạo một dịch vụ sức khoẻ cần có quyền BODY_SENSORS
, thì ứng dụng hiện không có quyền đó và hệ thống sẽ gửi một ngoại lệ.
(Điều này không áp dụng nếu đó là một dịch vụ sức khoẻ cần có các quyền khác, chẳng hạn như ACTIVITY_RECOGNITION
.) Việc gọi PermissionChecker.checkSelfPermission()
không ngăn được vấn đề này. Nếu ứng dụng của bạn có quyền sử dụng khi đang dùng và gọi checkSelfPermission()
để kiểm tra xem ứng dụng có quyền đó hay không, thì phương thức này sẽ trả về PERMISSION_GRANTED
ngay cả khi ứng dụng ở chế độ nền. Khi phương thức này trả về PERMISSION_GRANTED
, tức là "ứng dụng của bạn có quyền này trong khi ứng dụng đang được dùng".
Vì lý do này, nếu dịch vụ trên nền trước của bạn cần có quyền sử dụng khi đang dùng, bạn phải gọi Context.startForegroundService()
hoặc Context.bindService()
trong khi ứng dụng của bạn có một hoạt động hiển thị, trừ phi dịch vụ đó thuộc một trong các trường hợp miễn trừ được xác định.
Các trường hợp được miễn trừ hạn chế đối với quyền truy cập khi đang sử dụng
Trong một số trường hợp, ngay cả khi dịch vụ trên nền trước được khởi động trong khi ứng dụng chạy ở chế độ nền, thì dịch vụ đó vẫn có thể truy cập thông tin vị trí, camera và micrô trong khi ứng dụng chạy ở chế độ nền trước ("trong khi sử dụng").
Trong những trường hợp tương tự, nếu dịch vụ khai báo một loại dịch vụ trên nền trước là location
và được khởi động bởi một ứng dụng có quyền ACCESS_BACKGROUND_LOCATION
, thì dịch vụ này có thể truy cập vào thông tin vị trí mọi lúc, ngay cả khi ứng dụng chạy ở chế độ nền.
Danh sách sau đây chứa những trường hợp này:
- Một thành phần hệ thống sẽ khởi động dịch vụ.
- Dịch vụ này bắt đầu bằng cách tương tác với tiện ích ứng dụng.
- Dịch vụ này bắt đầu bằng cách tương tác với một thông báo.
- Dịch vụ này bắt đầu dưới dạng một
PendingIntent
được gửi từ một ứng dụng khác, có thể nhìn thấy. - Dịch vụ này bắt đầu bằng một ứng dụng là trình kiểm soát chính sách thiết bị chạy ở chế độ chủ sở hữu thiết bị.
- Dịch vụ này bắt đầu bằng một ứng dụng cung cấp
VoiceInteractionService
. - Dịch vụ này bắt đầu bằng một ứng dụng có quyền đặc biệt
START_ACTIVITIES_FROM_BACKGROUND
.
Xác định những dịch vụ bị ảnh hưởng trong ứng dụng của bạn
Khi kiểm thử ứng dụng, hãy bắt đầu các dịch vụ trên nền trước của ứng dụng. Nếu một dịch vụ đã bắt đầu có quyền truy cập hạn chế vào vị trí, micrô và camera, thì thông báo sau sẽ xuất hiện trong Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME