포그라운드 서비스

포그라운드 서비스는 사용자가 인지할 수 있는 작업을 수행합니다.

포그라운드 서비스는 상태 표시줄을 표시합니다. 알림을 설정하여 앱이 포그라운드에서 작업을 수행하고 시스템 리소스를 소비하고 있을 때 발생합니다.

포그라운드 서비스를 사용하는 앱의 예는 다음과 같습니다.

  • 포그라운드 서비스에서 음악을 재생하는 음악 플레이어 앱 알림 현재 재생 중인 노래가 표시될 수 있습니다.
  • 포그라운드 서비스에서 사용자의 달리기를 기록한 후 권한을 요청할 수 있습니다. 알림에는 이동했을 수 있습니다.

앱에서 작업을 실행해야 할 때만 포그라운드 서비스 사용 사용자와 직접 상호작용하지 않을 때도 눈에 띄는 앱 액션의 중요도가 낮아 최소 우선순위 알림, 배경 만들기 task를 사용하세요.

이 문서에서는 포그라운드 서비스 사용에 필요한 권한을 설명합니다. 포그라운드 서비스를 시작하고 백그라운드에서 삭제하는 방법을 설명합니다. 또한 특정 사용 사례를 포그라운드 서비스 유형과 연결하는 방법을 설명합니다. 포그라운드 서비스를 시작할 때 적용되는 액세스 제한 백그라운드로 실행 중인 앱으로부터 액세스할 수 있습니다

사용자는 기본적으로 알림을 닫을 수 있습니다.

Android 13 (API 수준 33)부터 사용자가 알림을 닫을 수 있음 기본적으로 포그라운드 서비스와 연결됩니다. 이를 위해 사용자는 동작입니다. 일반적으로 알림은 포그라운드 서비스가 중지되거나 삭제되지 않는 한 닫히지 않습니다. 볼 수 있습니다

사용자가 알림을 닫을 수 없도록 하려면 다음을 전달합니다. setOngoing()true Notification.Builder를 사용하여 알림을 만들 때 이 메서드를 사용해야 합니다.

알림을 즉시 표시하는 서비스

포그라운드 서비스가 다음 특성 중 하나 이상을 갖는 경우, 시스템은 서비스가 시작된 직후에 관련 알림을 표시하고 Android 12 이상을 실행하는 기기에서도 마찬가지입니다.

Android 13 (API 수준 33) 이상에서 사용자가 알림 권한 홈 화면에 포그라운드 서비스와 관련된 알림이 계속 작업 관리자 알림 창에는 표시되지 않습니다.

매니페스트에서 포그라운드 서비스 선언

앱의 매니페스트에서 각 앱의 포그라운드 서비스를 선언합니다. <service> 포함 요소가 포함됩니다. 각 서비스에 대해 android:foregroundServiceType 속성 서비스가 수행하는 작업의 종류를 선언할 수 있습니다.

예를 들어 앱에서 음악을 재생하는 포그라운드 서비스를 만들면 서비스를 다음과 같이 선언할 수 있습니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
  <application ...>

    <service
        android:name=".MyMediaPlaybackService"
        android:foregroundServiceType="mediaPlayback"
        android:exported="false">
    </service>
  </application>
</manifest>

서비스에 여러 유형을 적용하는 경우 |로 구분하세요. 연산자와 같습니다. 예를 들어 카메라와 마이크를 사용하는 서비스 다음과 같이 선언합니다.

android:foregroundServiceType="camera|microphone"

포그라운드 서비스 권한 요청하기

Android 9 (API 수준 28) 이상을 타겟팅하고 포그라운드 서비스를 사용하는 앱 모든 포드의 FOREGROUND_SERVICE 드림 을 선언할 수 있습니다. 이는 정상적인 권한이 부여되므로 시스템은 요청하는 앱에 자동으로 부여합니다.

또한 앱이 API 수준 34 이상을 대상으로 하는 경우 포그라운드 서비스가 실행하게 될 작업의 종류에 대한 적절한 권한 유형 하고 있습니다. 각 포그라운드 서비스 유형은 해당하는 권한 유형이 있는지 확인하세요. 예를 들어 앱이 포그라운드 서비스에서 실행 중인 경우 FOREGROUND_SERVICE 드림 및 FOREGROUND_SERVICE_CAMERA 권한을 부여할 수 있습니다 이들은 모두 정상 권한이므로 시스템이 목록에 있는 경우 자동으로 삭제됩니다

<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>

포그라운드 서비스 기본 요건

Android 14 (API 수준 34)부터 포그라운드 서비스를 실행할 때 시스템이 서비스 유형에 따라 특정 기본 요건을 확인합니다. 예를 들어 location 유형의 포그라운드 서비스를 실행하려고 하면 시스템은 앱에 ACCESS_COARSE_LOCATION 또는 ACCESS_FINE_LOCATION 권한 그러지 않으면 시스템에서 SecurityException

따라서 필수 기본 요건을 충족하는지 확인해야 합니다. 전에 확인해야 합니다. 포그라운드 서비스 type 문서 에는 각 포그라운드 서비스 유형의 필수 기본 요건이 나열되어 있습니다.

포그라운드 서비스 시작

시스템에 서비스를 포그라운드 서비스로 실행하도록 요청하기 전에 먼저 서비스 자체가 포함됩니다.

Kotlin

val intent = Intent(...) // Build the intent for the service
context.startForegroundService(intent)

자바

Context context = getApplicationContext();
Intent intent = new Intent(...); // Build the intent for the service
context.startForegroundService(intent);

서비스 내부(일반적으로 onStartCommand())에서 다음을 요청할 수 있습니다. 서비스가 포그라운드에서 실행되는지 확인합니다 이렇게 하려면 ServiceCompat.startForeground() 드림 (androidx-core 1.12 이상에서 사용 가능) 이 메서드는 다음을 가져옵니다. 매개변수:

이러한 유형은 매니페스트에 선언된 유형의 하위 집합일 수 있습니다. 특정 사용 사례에 따라 다를 수 있습니다 그런 다음 더 많은 서비스 유형을 추가해야 하는 경우 startForeground()를 다시 호출할 수 있습니다.

예를 들어 피트니스 앱이 달리기 추적기 서비스를 실행한다고 가정해 보겠습니다. location 정보가 필요하지만 미디어를 재생할 필요가 있을 수도 있고 필요하지 않을 수도 있습니다. 나 매니페스트에서 locationmediaPlayback를 모두 선언해야 합니다. 만약 사용자가 달리기를 시작하고 자신의 위치를 추적하기를 원할 경우 앱은 다음을 호출해야 합니다. startForeground()하고 ACCESS_FINE_LOCATION 권한만 전달합니다. 그런 다음 사용자가 오디오 재생을 시작하려면 startForeground()를 다시 호출하고 모든 포그라운드 서비스 유형 (이 경우에는 ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK).

다음은 카메라 포그라운드 서비스를 실행하는 예입니다.

Kotlin

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 =
            PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA)
    if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) {
        // 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)
        }
        // ...
    }
  }
}

자바

public class MyCameraService extends Service {

    private void 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.
        int 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 {
            Notification notification =
                new NotificationCompat.Builder(this, "CHANNEL_ID")
                    // Create the notification to display while the service
                    // is running
                    .build();
            int type = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
            }
            ServiceCompat.startForeground(
                    /* service = */ this,
                    /* id = */ 100, // Cannot be 0
                    /* notification = */ notification,
                    /* foregroundServiceType = */ type
            );
        } catch (Exception e) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
                    e instanceof ForegroundServiceStartNotAllowedException
            ) {
                // App not in a valid state to start foreground service
                // (e.g started from bg)
            }
            // ...
        }
    }

    //...
}

포그라운드에서 서비스 삭제

서비스를 포그라운드에서 삭제하려면 다음을 호출합니다. stopForeground() 이 메서드는 상태 표시줄을 삭제할지 여부를 나타내는 부울을 사용합니다. 확인할 수 있습니다 서비스는 계속 실행됩니다.

포그라운드에서 실행되는 동안 서비스를 중지하면 삭제됩니다.

포그라운드 서비스를 실행하는 앱의 사용자 시작 중지 처리

알림 창 하단에는
    현재 백그라운드에서 실행 중인 앱의 수 키를 누르면
    이 버튼을 누르면 여러 앱의 이름이 나열된 대화상자가 나타납니다. 이
    중지 버튼은 각 앱의 오른쪽에 있음
그림 1. 실행되는 기기의 작업 관리자 워크플로는 Android 13 이상을 실행해야 합니다.

Android 13 (API 수준 33)부터 사용자는 알림 창 현재 진행 중인 포그라운드 서비스가 있는 앱을 중지할 수 있습니다. 대상 SDK 버전에 따라 달라집니다 이러한 어포던스를 작업 관리자 화면에 액세스할 수 있는 현재 포그라운드 서비스를 실행 중인 경우

이 목록에는 활성 앱이라는 라벨이 지정되어 있습니다. 각 앱 옆에는 중지 버튼이 있습니다. 그림 1은 실행되는 기기의 작업 관리자 워크플로 Android 13

사용자가 앱 메뉴에서 앱 옆에 있는 Stop 버튼을 누르면 작업 관리자를 사용하면 다음 작업이 발생합니다.

  • 시스템이 메모리에서 앱을 삭제합니다. 따라서 전체 앱이 중지되면 포그라운드 서비스만 실행되는 것이 아닙니다
  • 시스템에서 앱의 활동 백 스택을 삭제합니다.
  • 모든 미디어 재생이 중지됩니다.
  • 포그라운드 서비스와 관련된 알림이 삭제됩니다.
  • 앱은 기록에 남아 있습니다.
  • 예약된 작업은 예약된 시간에 실행됩니다.
  • 예약된 시간 또는 시간대에 울립니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.

사용자가 앱을 중단하는 동안과 그 후에 앱이 예상대로 작동하는지 테스트하려면 터미널 창에서 다음 ADB 명령어를 실행합니다.

adb shell cmd activity stop-app PACKAGE_NAME

예외

시스템은 이어지는 섹션에서 설명하는 특정 유형의 앱에 대해 여러 수준의 예외를 제공합니다.

예외는 프로세스가 아닌 앱별로 적용됩니다. 시스템이 하나의 앱에서 하나의 프로세스에 예외를 제공한 경우 이 앱의 다른 모든 프로세스에도 예외가 제공됩니다.

작업 관리자에 전혀 표시되지 않음

다음 앱은 포그라운드 서비스를 실행할 수 있으며 작업 관리자 사용 안함:

사용자가 중지할 수 없음

다음 유형의 앱이 포그라운드 서비스를 실행하면 중지 버튼이 표시되지 않는 경우 사용자가 탭할 앱의 이름:

포그라운드 서비스 대신 목적에 맞게 빌드된 API 사용

많은 사용 사례의 경우 작업에 사용할 수 있는 플랫폼 또는 Jetpack API가 있습니다. 다른 용도로 포그라운드 서비스를 사용할 수 있습니다. 적합한 거의 항상 포그라운드를 사용하는 대신 이 API를 사용해야 합니다. 있습니다. 목적에 맞게 빌드된 API는 대체로 사용 사례별 자체적으로 빌드해야 하는 기능을 제공합니다. 예를 들어 Bubbles API는 채팅 풍선 기능을 구현해야 하는 메시지 앱입니다.

포그라운드 서비스 유형 목록에 대한 문서 포그라운드 서비스 대신 사용할 수 있는 좋은 대안이 될 수 있습니다.

백그라운드에서 포그라운드 서비스 시작에 관한 제한사항

Android 12 이상을 타겟팅하는 앱은 포그라운드를 시작할 수 없습니다. 실행 중인 일부 서비스에만 액세스할 수 있습니다. 사례를 참조하세요. 앱에서 앱이 백그라운드에서 실행되는 동안 포그라운드 서비스 및 포그라운드 서비스가 예외적인 경우 중 하나를 충족하지 않으면 시스템에서 ForegroundServiceStartNotAllowedException

또한 앱에서 시작되어야 하는 포그라운드 서비스를 실행하려는 경우 사용 중 권한 (예: 생체 신호 센서, 카메라, 마이크 또는 위치 권한) 앱이 백그라운드에 있는 동안에는 서비스를 만들 수 없습니다. 앱이 백그라운드 시작 예외 중 하나에 해당하더라도 제한되기 때문입니다. 그 이유는 다음 섹션에 설명되어 있습니다. 사용 중 필요한 포그라운드 서비스 시작 권한이 있는지 확인합니다.

백그라운드 시작 제한 예외

다음과 같은 상황에서 앱이 실행되는 동안에도 포그라운드 서비스를 시작할 수 있습니다. 앱이 백그라운드에서 실행됩니다.

사용 중 권한이 필요한 포그라운드 서비스 시작에 관한 제한사항

Android 14 (API 수준 34) 이상에서는 사용 중 권한이 필요한 포그라운드 서비스를 시작하는지 여부

앱이 Android 14 이상을 타겟팅하는 경우 운영체제는 포그라운드 서비스를 생성할 때 앱에 필요한 모든 해당 서비스 유형에 적합한 권한을 부여해야 합니다 예를 들어 포그라운드 서비스 유형 마이크는 현재 앱이 현재 RECORD_AUDIO 권한을 부여했는지 확인합니다. 이 권한이 없으면 시스템에서 SecurityException

사용 중 권한의 경우 이로 인해 잠재적인 문제가 발생합니다. 앱에 앱이 실행되는 동안에만 포그라운드 상태가 될 수 있습니다. 앱이 백그라운드에 있으며 앱에서 카메라, 위치 또는 마이크 유형의 포그라운드 서비스가 있을 경우 시스템이 이를 인식하고 앱에 현재 필수 권한이 없어서 다음과 같은 오류가 발생합니다. SecurityException입니다.

마찬가지로 앱이 백그라운드에 있으며 BODY_SENSORS_BACKGROUND 권한이 필요한 건강 관리 서비스인 경우 에 현재 해당 권한이 없으므로 시스템에서 예외가 발생합니다. (다른 권한이 필요한 건강 서비스인 경우에는 적용되지 않습니다. ACTIVITY_RECOGNITION 등입니다.) 전화 걸기 PermissionChecker.checkSelfPermission() 이 문제를 방지하지 않습니다. 앱에 사용 중 권한이 있는 경우 checkSelfPermission()를 호출하여 해당 권한이 있는지 확인합니다. 앱이 백그라운드에 있더라도 PERMISSION_GRANTED를 반환합니다. 이 메서드가 PERMISSION_GRANTED를 반환하면 '앱에 이 권한이 있습니다. 앱 사용 중에만

따라서 포그라운드 서비스에 사용 중 권한이 필요한 경우 Context.startForegroundService() 또는 Context.bindService()를 호출해야 하는 동안 서비스가 정의된 예외.

사용 중 권한 제한 예외

앱이 실행 중일 때 포그라운드 서비스가 시작되더라도 실행 백그라운드에서 앱이 계속 위치 정보에 액세스할 수 있습니다. 앱이 포그라운드에서 실행되는 동안 카메라 및 마이크 정보 ('사용 중').

이와 같은 상황에서 서비스가 포그라운드 서비스 유형location이며 는 ACCESS_BACKGROUND_LOCATION 권한을 부여하지 않으면 이 서비스는 앱이 백그라운드에서 실행됩니다.

다음 목록에는 다음과 같은 상황이 나와 있습니다.

  • 시스템 구성요소가 서비스를 시작합니다.
  • 서비스는 앱과의 상호작용으로 시작됨 위젯과 같은 다른 위젯을 사용하는 방법을 자세히 알아볼 수 있습니다.
  • 서비스는 알림과 상호작용하여 시작됩니다.
  • 서비스는 PendingIntent: 눈에 잘 띄는 앱을 만들 수 있습니다.
  • 서비스가 기기 정책인 앱에 의해 시작됨 컨트롤러를 사용하는 것이 좋습니다.
  • 서비스가 VoiceInteractionService를 제공하는 앱에 의해 시작됩니다.
  • 서비스가 START_ACTIVITIES_FROM_BACKGROUND 독점 권한입니다.
앱에서 영향을 받는 서비스 확인

앱을 테스트할 때 포그라운드 서비스를 시작합니다. 시작된 서비스에 위치, 마이크 및 카메라 액세스 제한이 적용된 경우 다음 메시지가 Logcat에 표시됩니다.

Foreground service started from background can not have \
location/camera/microphone access: service SERVICE_NAME