안드로이드에서 화면이 꺼져도 계속 도는 작업을 위한 장치다. 대가로 상시 알림을 띄워야 한다 — "이 앱이 지금 뭔가 하고 있다"를 사용자가 알 수 있게.
왜 그냥 서비스로는 안 되나
일반 백그라운드 서비스는 시스템이 언제든 죽인다. 메모리가 부족하면, 사용자가 앱을 나가면, Doze 에 들어가면 정지한다. 차량과의 연결처럼 끊기면 안 되는 것은 포그라운드로 올려야 한다.
일반 서비스 시스템이 임의로 종료 · 알림 없음
포그라운드 우선순위 상승 · 상시 알림 의무 · Doze 영향 축소
Android 14 — 타입 선언 의무화
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<service android:name=".VehicleLinkService"
android:foregroundServiceType="connectedDevice" />
타입을 안 쓰면 MissingForegroundServiceTypeException 으로 앱이 죽는다. 경고가 아니라 크래시다.
타입은 용도별로 나뉘어 있다 — location, camera, mediaPlayback, dataSync, connectedDevice 등. BLE 로 외부 기기와 붙어 있는 경우가 connectedDevice 다.
그리고 타입마다 전제 조건이 붙는다. connectedDevice 는 런타임에 BLUETOOTH_CONNECT·BLUETOOTH_SCAN·BLUETOOTH_ADVERTISE·UWB_RANGING 중 하나 이상이 실제로 부여돼 있어야 시작된다. 매니페스트에 선언만 해 두고 사용자가 권한을 거부한 상태면 못 뜬다.
Android 15 — 백그라운드에서 못 띄운다
앱이 화면에 없는 상태에서는 포그라운드 서비스를 새로 시작할 수 없다. 이게 차량 앱에 직격이다.
부팅 직후 → 앱이 안 떠 있다 → 서비스 시작 불가
사용자가 앱 종료 후 → 차가 가까워져도 스스로 못 뜬다
우회 경로가 셋이다.
| 방법 | 한계 |
|---|---|
BOOT_COMPLETED 수신 | 부팅 때 한 번뿐 |
| WorkManager 주기 실행 | 최소 15분 간격 — 즉시성이 없다 |
| Companion Device Manager | 근접 시 시스템이 깨워 준다 |
세 번째가 정답이다. CDM 은 이 제약의 면제 권한을 자동으로 준다.
결론 — 직접 붙들지 않는다
포그라운드 서비스로 연결을 유지하려 하면 배터리 최적화 예외 요청, 상시 알림, 제조사별 태스크 킬러와 계속 싸우게 된다. CDM 에 수명 관리를 맡기고, 서비스는 차가 가까울 때만 뜨게 하는 게 지금의 권장 구조다.