Quy định hạn chế khi bắt đầu dịch vụ trên nền trước từ chế độ nền

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 vài trường hợp đặc biệt. Nếu một ứng dụng cố gắng bắt đầu 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 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 miễn trừ khỏi các quy định hạn chế về việc bắt đầu ở chế độ nền. Lý do của việc này được giải thích trong phần Hạn chế về việc khởi động các dịch vụ trên nền trước cần có quyền khi đang sử dụng.

Miễn các hạn chế khi bắt đầu chạy ở chế độ nền

Trong các 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 chạy ở chế độ nền:

Các hạn chế về việc bắt đầu các dịch vụ trên nền trước cần có quyền khi đang sử dụng

Trên Android 14 (API cấp 34) trở lên, bạn cần lưu ý 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 quyền khi đang sử 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 thời điểm bạn tạo dịch vụ trên nền trước để đảm bảo ứng dụng của bạn có tất cả quyền thích 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 micrô, 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 các quyền khi đang sử dụng, điều này có thể gây ra vấn đề. Nếu có quyền khi đang sử dụng, ứng dụng của bạn chỉ có quyền đó khi đang ở chế độ nền trước. Điều này có nghĩa là nếu ứng dụng của bạn đang chạy ở chế độ nền và cố gắng tạo một dịch vụ trên nền trước thuộc loại máy ảnh, vị trí hoặc micrô, thì hệ thống sẽ 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à sẽ gửi một SecurityException.

Tương tự, nếu ứng dụng của bạn đang chạy ở chế độ nền và tạo một dịch vụ sức khoẻ cần 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à dịch vụ y tế cần các quyền khác, như ACTIVITY_RECOGNITION.) Việc gọi PermissionChecker.checkSelfPermission() sẽ không ngăn chặn được vấn đề này. Nếu ứng dụng của bạn có quyền khi đang sử 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 đang chạy ở 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 sử dụng".

Vì lý do này, nếu dịch vụ trên nền trước của bạn cần quyền khi đang sử 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ừ đã xác định.

Miễn khỏi các hạn chế về quyền 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, dịch vụ này vẫn có thể truy cập thông tin vị trí, máy ảnh 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 loại dịch vụ trên nền trướclocation và được một ứng dụng có quyền ACCESS_BACKGROUND_LOCATION khởi động, thì dịch vụ này có thể truy cập 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 bao gồm các 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ụ bắt đầu bằng cách tương tác với tiện ích ứng dụng.
  • Dịch vụ bắt đầu bằng cách tương tác với một thông báo.
  • Dịch vụ bắt đầu dưới dạng một PendingIntent được gửi từ một ứng dụng hiển thị khác.
  • Dịch vụ này bắt đầu bằng một ứng dụng là trình điều khiển 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 quyền START_ACTIVITIES_FROM_BACKGROUND.

Xác định những dịch vụ bị ảnh hưởng trong ứng dụng

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 hạn chế quyền truy cập vào vị trí, micrô và máy ảnh, 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