앱이 타겟팅하는 API 수준에 따라 앱이 포그라운드 서비스를 실행할 수 있는 시기에 몇 가지 제한사항이 있습니다.
Android 12 (API 수준 31) 이상을 타겟팅하는 앱은 몇 가지 예외를 제외하고 앱이 백그라운드에 있는 동안 포그라운드 서비스를 시작할 수 없습니다. 자세한 내용과 이 규칙의 예외에 관한 내용은 백그라운드에서 포그라운드 서비스를 시작할 때 적용되는 제한사항을 참고하세요.
Android 14 (API 수준 34) 이상을 타겟팅하는 앱은 포그라운드 서비스 유형에 적합한 권한을 요청해야 합니다. 앱이 서비스를 포그라운드로 승격하려고 하면 시스템에서 적절한 권한이 있는지 확인하고 앱에 권한이 누락된 경우 SecurityException이 발생합니다. 예를 들어 location 유형의 포그라운드 서비스를 실행하려고 하면 시스템은 앱에 이미 ACCESS_COARSE_LOCATION 또는 ACCESS_FINE_LOCATION 권한이 있는지 확인합니다. 포그라운드 서비스 유형 문서에는 각 포그라운드 서비스 유형에 필요한 필수사항이 나열되어 있습니다.
서비스 실행
포그라운드 서비스를 실행하려면 먼저 일반 (포그라운드 아님) 서비스로 실행해야 합니다.
Kotlin
valintent=Intent(...)// Build the intent for the servicecontext.startForegroundService(intent)
자바
Contextcontext=getApplicationContext();Intentintent=newIntent(...);// Build the intent for the servicecontext.startForegroundService(intent);
코드에 관한 핵심 사항
코드 스니펫이 서비스를 실행합니다. 하지만 서비스가 아직 포그라운드에서 실행되고 있지 않습니다. 서비스 자체 내에서 ServiceCompat.startForeground()를 호출하여 서비스를 포그라운드 서비스로 승격해야 합니다.
특정 사용 사례에 따라 startForeground()에 전달하는 포그라운드 서비스 유형 매니페스트에 선언된 유형 그런 다음 서비스 유형을 더 추가해야 하는 경우 startForeground()를 다시 호출하면 됩니다.
예를 들어 피트니스 앱이 항상 location 정보가 필요하지만 미디어 재생이 필요할 수도 있고 필요하지 않을 수도 있는 러닝 추적기 서비스를 실행한다고 가정해 보겠습니다. 매니페스트에서 location와 mediaPlayback을 모두 선언해야 합니다. 사용자가 러닝을 시작하고 위치만 추적하려는 경우 앱은 startForeground()를 호출하고 ACCESS_FINE_LOCATION 권한만 전달해야 합니다. 그런 다음 사용자가 오디오 재생을 시작하려고 하면 startForeground()를 다시 호출하고 모든 포그라운드 서비스 유형의 비트 조합 (이 경우 ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK)을 전달합니다.
다음 예는 카메라 서비스가 포그라운드 서비스로 승격하는 데 사용하는 코드를 보여줍니다.
Kotlin
classMyCameraService:Service(){privatefunstartForeground(){// 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.valcameraPermission=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{valnotification=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&&eisForegroundServiceStartNotAllowedException){// App not in a valid state to start foreground service// (e.g. started from bg)}// ...}}}
자바
publicclassMyCameraServiceextendsService{privatevoidstartForeground(){// 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.intcameraPermission=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{Notificationnotification=newNotificationCompat.Builder(this,"CHANNEL_ID")// Create the notification to display while the service// is running.build();inttype=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(Exceptione){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S&&einstanceofForegroundServiceStartNotAllowedException){// App not in a valid state to start foreground service// (e.g started from bg)}// ...}}//...}
코드에 관한 핵심 사항
앱이 이미 매니페스트에서 CAMERA 권한이 필요하다고 선언했습니다. 하지만 앱은 런타임에 사용자가 해당 권한을 부여했는지도 확인해야 합니다. 앱에 실제로 올바른 권한이 없는 경우 사용자에게 문제를 알려야 합니다.
Android 플랫폼의 여러 버전에서 다양한 포그라운드 서비스 유형이 도입되었습니다. 이 코드는 실행 중인 Android 버전을 확인하고 적절한 권한을 요청합니다.
코드는 허용되지 않는 상황에서 포그라운드 서비스를 시작하려고 하는 경우 (예: 앱이 백그라운드에 있는 동안 서비스를 포그라운드로 승격하려고 하는 경우) ForegroundServiceStartNotAllowedException를 확인합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-27(UTC)
[null,null,["최종 업데이트: 2025-08-27(UTC)"],[],[],null,["There are two steps to launching a foreground service from your app. First, you\nmust start the service by calling\n[`context.startForegroundService()`](/reference/android/content/Context#startForegroundService(android.content.Intent)). Then, have the\nservice call [`ServiceCompat.startForeground()`](/reference/androidx/core/app/ServiceCompat#startForeground(android.app.Service,int,android.app.Notification,int)) to promote\nitself into a foreground service.\n\nPrerequisites\n\nDepending on which API level your app targets, there are some restrictions on\nwhen an app can launch a foreground service.\n\n- Apps that target Android 12 (API level 31) or higher are not allowed to\n start a foreground service while the app is in the background, with a few\n specific exceptions. For more information, and information about the\n exceptions to this rule, see [Restrictions on starting a foreground service\n from the background](/develop/background-work/services/fgs/restrictions-bg-start).\n\n- Apps that target Android 14 (API level 34) or higher must request the\n appropriate\n permissions for the foreground service type. When the app attempts to\n promote a service to the foreground, the system checks for the appropriate\n permissions and throws throws [`SecurityException`](/reference/java/lang/SecurityException) if\n the app is missing any. For example, if you try to launch a foreground\n service of type `location`, the system checks to make sure your app already\n has either the `ACCESS_COARSE_LOCATION` or `ACCESS_FINE_LOCATION`\n permission. The [foreground service type](/develop/background-work/services/fgs/service-types) documentation lists the\n required prerequisites for each foreground service type.\n\nLaunch a service\n\nIn order to launch a foreground service, you must first launch it as an\nordinary (non-foreground) service: \n\nKotlin \n\n```kotlin\nval intent = Intent(...) // Build the intent for the service\ncontext.startForegroundService(intent)\n```\n\nJava \n\n```java\nContext context = getApplicationContext();\nIntent intent = new Intent(...); // Build the intent for the service\ncontext.startForegroundService(intent);\n```\n\nKey points about the code\n\n- The code snippet launches a service. However, the service is not yet running in the foreground. Inside the service itself, you need to call `ServiceCompat.startForeground()` to promote the service to a foreground service.\n\nPromote a service to the foreground\n\nOnce a service is running, you need to call\n[`ServiceCompat.startForeground()`](/reference/androidx/core/app/ServiceCompat#startForeground(android.app.Service,int,android.app.Notification,int)) to request that the service\nrun in the foreground. Ordinarily you would call this method in the service's\n[`onStartCommand()`](/reference/android/app/Service#onStartCommand(android.content.Intent,%20int,%20int)) method.\n\n`ServiceCompat.startForeground()` takes the following parameters:\n\n- The service.\n- A positive integer that uniquely identifies the service's notification in the status bar.\n- The [`Notification`](/reference/android/app/Notification) object itself.\n- The [foreground service type or types](/develop/background-work/services/fgs/service-types) identifying the work done by the service\n\n| **Note:** If you pass a foreground service type to `startForeground` that you did not declare in the manifest, the system throws `IllegalArgumentException`.\n\nThe foreground service types you pass to `startForeground()`\n[types declared in the manifest](/develop/background-work/services/fgs/service-types#declare-fgs), depending on the specific\nuse case. Then, if you need to add more service types, you can call\n`startForeground()` again.\n\nFor example, suppose a fitness app runs a running-tracker service that always\nneeds `location` information, but might or might not need to play media. You\nwould need to declare both `location` and `mediaPlayback` in the manifest. If a\nuser starts a run and just wants their location tracked, your app should call\n`startForeground()` and pass just the `ACCESS_FINE_LOCATION` permission. Then,\nif the user wants to start playing audio, call `startForeground()` again and\npass the bitwise combination of all the foreground service types (in this case,\n`ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK`).\n| **Note:** The status bar notification must use a priority of [`PRIORITY_LOW`](/reference/androidx/core/app/NotificationCompat#PRIORITY_LOW) or higher. If your app attempts to use a notification that has a lower priority than `PRIORITY_LOW`, the system adds a message to the notification drawer, alerting the user to the app's use of a foreground service.\n\nThe following example shows the code a camera service would use to promote\nitself to a foreground service: \n\nKotlin \n\n```kotlin\nclass MyCameraService: Service() {\n\n private fun startForeground() {\n // Before starting the service as foreground check that the app has the\n // appropriate runtime permissions. In this case, verify that the user has\n // granted the CAMERA permission.\n val cameraPermission =\n PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA)\n if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) {\n // Without camera permissions the service cannot run in the foreground\n // Consider informing user or updating your app UI if visible.\n stopSelf()\n return\n }\n\n try {\n val notification = NotificationCompat.Builder(this, \"CHANNEL_ID\")\n // Create the notification to display while the service is running\n .build()\n ServiceCompat.startForeground(\n /* service = */ this,\n /* id = */ 100, // Cannot be 0\n /* notification = */ notification,\n /* foregroundServiceType = */\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.R) {\n ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA\n } else {\n 0\n },\n )\n } catch (e: Exception) {\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.S\n && e is ForegroundServiceStartNotAllowedException) {\n // App not in a valid state to start foreground service\n // (e.g. started from bg)\n }\n // ...\n }\n }\n}\n```\n\nJava \n\n```java\npublic class MyCameraService extends Service {\n\n private void startForeground() {\n // Before starting the service as foreground check that the app has the\n // appropriate runtime permissions. In this case, verify that the user\n // has granted the CAMERA permission.\n int cameraPermission =\n ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);\n if (cameraPermission == PackageManager.PERMISSION_DENIED) {\n // Without camera permissions the service cannot run in the\n // foreground. Consider informing user or updating your app UI if\n // visible.\n stopSelf();\n return;\n }\n\n try {\n Notification notification =\n new NotificationCompat.Builder(this, \"CHANNEL_ID\")\n // Create the notification to display while the service\n // is running\n .build();\n int type = 0;\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.R) {\n type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;\n }\n ServiceCompat.startForeground(\n /* service = */ this,\n /* id = */ 100, // Cannot be 0\n /* notification = */ notification,\n /* foregroundServiceType = */ type\n );\n } catch (Exception e) {\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.S &&\n e instanceof ForegroundServiceStartNotAllowedException\n ) {\n // App not in a valid state to start foreground service\n // (e.g started from bg)\n }\n // ...\n }\n }\n\n //...\n}\n```\n\nKey points about the code\n\n- The app has already declared in the manifest that it needs the `CAMERA` permission. However, the app also has to check at runtime to make sure the user granted that permission. If the app does not actually have the correct permissions, it should let the user know about the problem.\n- Different foreground service types were introduced with different versions of the Android platform. This code checks what version of Android it's running on and requests the appropriate permissions.\n- The code checks for `ForegroundServiceStartNotAllowedException` in case it's trying to start a foreground service in a situation that's not allowed (for example, if it's trying to promote the service to the foreground [while\n the app is in the background](/develop/background-work/services/fgs/restrictions-bg-start))."]]