Hanbit the Developer
Android Document | Foreground services > Overview 본문
User can dismiss notification by default
Android 13(API level 33)부터 사용자는 foreground service 관련 알림을 제거할 수 있다. 기존에는 foreground service가 꺼질 때까지 제거할 수 없었다.
만약 non-dismissable하게 하고 싶다면, Notification.Builder로 알림을 생성할 때 setOngoing(true) 메소드를 사용하라.
Services that show a notification immediately
아래 조건 중 하나를 충족하면 서비스 시작 시 시스템이 알림을 띄운다:
- 서비스가 action button을 포함한 알림과 연관될 때
- 서비스가 mediaPlayback, mediaProjection, or phoneCall 유형의 타입(foregroundServiceType)을 가질 때
- 서비스가 알림 설정 시 setForegroundServiceBehavior()에 FOREGROUND_SERVICE_IMMEDIATE를 넣어 호출할 때
Android 13(API level 33) 이상에서 알림 권한이 없을 때, notification drawer에서는 보이지 않지만 여전히 Task Manager에서 notice를 받게 된다.
Declare foreground services in your manifest
선언 시 서비스 유형을 foregroundServiceType를 통해 지정한다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</manifest>
android:foregroundServiceType="camera|microphone"
API 레벨별 필수로 명시해야 하는 서비스 타입은 다음과 같다.
- API level 29 or higher: location
- API level 30 or higher: camera, microphone
- API level 34 or higher: 모든 foreground service에 서비스 타입을 명시해야 한다.
만약 이를 어기면, startForeground() 호출 시 시스템이 MissingForegroundServiceTypeException 예외를 던진다.
Request the foreground service permissions
Android 9(API level 28) 이상 버전에서 FOREGROUND_SERVICE 권한을 매니페스트 파일에 명시해야 한다.
API level 34 이상 버전에서는 foreground service가 하는 작업에 대해 적절한 권한을 요청해야 한다. 각 foreground service type은 그에 상응하는 권한 타입을 갖고 있다.
예를 들어 카메라를 사용하는 서비스는 다음과 같이 선언해야 한다:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<application ...>
...
</application>
</manifest>
Foreground service prerequisites
Android 14(API level 34)부터 foreground service 시작 전에 해당 시스템이 서비스가 사용하는 모든 권한이 있는지 체크한다.(권한이 없을 경우 예외를 던짐)
Start a foreground service
val intent = Intent(...) // Build the intent for the service
context.startForegroundService(intent)
class MyCameraService: Service() {
private fun startForeground() {
// Before starting the service as foreground check that the app has the
// appropriate runtime permissions. In this case, verify that the user has
// granted the CAMERA permission.
val cameraPermission =
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
if (cameraPermission == PackageManager.PERMISSION_DENIED) {
// Without camera permissions the service cannot run in the foreground
// Consider informing user or updating your app UI if visible.
stopSelf()
return
}
try {
val notification = NotificationCompat.Builder(this, "CHANNEL_ID")
// Create the notification to display while the service is running
.build()
ServiceCompat.startForeground(
/* service = */ this,
/* id = */ 100, // Cannot be 0
/* notification = */ notification,
/* foregroundServiceType = */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
} else {
0
},
)
} catch (e: Exception) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
&& e is ForegroundServiceStartNotAllowedException) {
// App not in a valid state to start foreground service
// (e.g. started from bg)
}
// ...
}
}
}
Remove a service from the foreground
stopForeground()를 호출하여 서비스를 제거할 수 있다. 인자로 boolean을 넣게 되는데, status bar notification 또한 제거할지 여부를 의미한다.
Handle user-initiated stopping of apps running foreground services
Android 13(API level 33)부터 notification drawer에서 Task Manager를 통해 작동하고 있는 foreground service를 중단할 수 있다.
중단 버튼을 누르면 다음과 같은 액션이 수행된다:
- 시스템이 앱을 메모리에서 제거한다. 이후 foreground service뿐만 아니라 앱 전체가 중단된다.
- 시스템이 백스택에서 앱을 제거한다.
- 미디어 재생이 중단된다.
- 해당 foreground service와 관련된 알림이 제거된다.
- 앱이 history에 남는다.
- 예약된 작업 및 알람이 예정된 시간에 작동한다.
중단 버튼을 누를 때 아무런 콜백도 없기 때문에, 백업을 원한다면 ApplicationExitInfo API의 REASON_USER_REQUESTED를 활용하라.
Exemptions
시스템은 앱 단위(프로세스 단위가 아닌)로 exemptions을 제공한다.
Task Manager에 노출되지 않음
- 시스템 레벨 앱
- ROLE_EMERGENCY 롤을 가지고 있는 안전 앱
- 데모 모드의 디바이스
유저가 중단할 수 없음
- Device owner apps: 디바이스 전체에 대한 관리 권한을 가지고 있는 앱
- Profile owner apps: 특정 사용자 프로필에 대한 관리 권한을 가지고 있는 앱
- Persistent apps: 시스템에 의해 중요하거나 필수적으로 간주되어 일반적으로는 종료될 수 없는 앱(예: 안드로이드 OS의 핵심 부분)
- Apps that have the ROLE_DIALER role
Use purpose-built API instead of foreground services
Bubbles API처럼 이미 잘 구성된 API가 있으므로 foreground service 구현만 고집하지는 말라.
foreground service types에 이러한 대체가 리스트업 되어있다.
Restrictions on starting a foreground service from the background
Android 12부터, 백그라운드에서 작동 중인 앱에서 포그라운드 서비스를 시작할 수 없다.(시도하게 되면 예외가 발생한다.)
Restrictions on starting foreground services that need while-in-use permissions
Android 14(API level 34) 이상에서, while-in-use 권한만 얻은 채로 해당 권한이 필요한 포그라운드 서비스를 실행하면 예외가 발생한다.
'Android' 카테고리의 다른 글
AnimatedVisibility 오버랩 이슈 해결 (1) | 2024.01.11 |
---|---|
ViewModel 분석 (0) | 2023.12.04 |
Android Document | About Services (1) | 2023.11.20 |
Android Lifecycle 분석 (0) | 2023.10.30 |
[Kotlin] Coroutines 예외 처리 방법 비교 (0) | 2023.08.28 |