Android/platform

[Android] 포그라운드 서비스(Foreground Service) 개요 및 구현 방법

mins9273 2024. 11. 29. 17:04
반응형

포그라운드 서비스(Foreground Service)

포그라운드 서비스는 사용자가 인식할 수 있는 중요한 작업을 수행하는 서비스입니다.

이 서비스는 백그라운드에서 실행되지만, 사용자에게 알림(Notification)을 통해 실행 중임을 지속적으로 알려야 합니다.

 

시스템 자원을 효율적으로 관리하면서 중요한 작업을 처리할 때 사용됩니다.

 

 

포그라운드 서비스의 특징

  1. 알림 표시
    포그라운드 서비스는 알림을 반드시 표시해야 합니다.
    알림은 사용자가 서비스를 인식할 수 있게 도와줍니다.
    알림은 상태 바나 알림 영역에 표시되며, 서비스가 실행되는 동안 계속 표시됩니다.
  2. 시스템 종료 방지
    일반적인 백그라운드 서비스는 자원 부족 시 시스템에 의해 종료될 수 있지만, 포그라운드 서비스는 시스템에 의해 종료되지 않습니다. 따라서 장시간 실행이 필요한 작업에 적합합니다.
  3. 장시간 실행
    포그라운드 서비스는 장시간 실행이 가능합니다.
    예를 들어, 음악 재생, GPS 네비게이션, 파일 다운로드와 같은 작업은 포그라운드 서비스로 실행하면 중단 없이 계속 작업을 수행할 수 있습니다.
    그렇기에 배터리 소모를 최소화하는 방법을 고려해야 합니다.
    GPS, 네트워크 사용 등의 자원을 많이 소모하는 작업을 최적화하여 배터리 소모를 줄여야 합니다.

  4. 사용자에게 중요한 작업 처리
    포그라운드 서비스는 사용자에게 중요한 작업을 처리할 때 주로 사용됩니다.
    사용자는 알림을 통해 서비스의 진행 상태를 확인할 수 있습니다.

 

 

사용 예시

  • 음악 재생 앱
    : 음악 앱은 포그라운드 서비스를 사용하여, 사용자가 음악을 재생 중임을 알림으로 표시하고, 앱을 최소화하거나 화면을 꺼도 음악이 계속 재생되도록 합니다.
  • GPS 네비게이션 앱
    : GPS 네비게이션 앱은 위치 정보를 제공하면서 음성 안내를 하기 위해 포그라운드 서비스를 사용합니다.
    이 서비스는 장시간 실행되므로 시스템에 의해 종료되지 않습니다.
  • 파일 다운로드
    : 대용량 파일 다운로드 작업은 포그라운드 서비스를 사용하여 다운로드 상태를 알림으로 표시하고, 다운로드 완료까지 서비스를 계속 실행할 수 있습니다.

 

 

포그라운드 서비스 구현 방법

1. 서비스 클래스 작성
Service 클래스를 확장하여 포그라운드 서비스를 구현합니다.

onStartCommand() 메서드에서 startForeground() 를 호출하여 서비스를 포그라운드로 설정합니다.

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.os.IBinder
import androidx.core.app.NotificationCompat

class MyForegroundService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 포그라운드 서비스 시작
        startForeground(1, createNotification())
        return START_STICKY // 서비스가 종료되지 않도록 함
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null // 바인딩되지 않는 서비스
    }

    private fun createNotification(): Notification {
        val channelId = "default"
        val channelName = "Foreground Service"
        val notificationManager = getSystemService(NotificationManager::class.java)

        // NotificationChannel 생성 (Android 8.0 이상에서 필요)
        val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
        notificationManager.createNotificationChannel(channel)

        // 알림 생성
        return NotificationCompat.Builder(this, channelId)
            .setContentTitle("포그라운드 서비스 실행 중")
            .setContentText("서비스가 계속 실행되고 있습니다.")
            .setSmallIcon(R.drawable.ic_service) // 원하는 아이콘으로 변경
            .build()
    }
}

 

 

 

2. 서비스 시작

서비스는 startService() 로 시작합니다.
포그라운드 서비스를 시작하려면 startForeground() 메서드를 호출하고, 알림을 반드시 제공해야 합니다.

val serviceIntent = Intent(this, MyForegroundService::class.java)
startService(serviceIntent)

 

 

3. 서비스 종료

포그라운드 서비스가 더 이상 필요하지 않으면 stopForeground() 와 stopSelf() 를 호출하여 서비스를 종료할 수 있습니다.

stopForeground(true)  // 알림 제거
stopSelf()  // 서비스 종료

 

 

4. AndroidManifest.xml 설정

서비스는 AndroidManifest.xml 에 등록해야 합니다.

<service
    android:name=".MyForegroundService"
    android:permission="android.permission.FOREGROUND_SERVICE" />

 

android.permission.FOREGROUND_SERVICE 권한은 Android 9 (API 28) 이상에서 필수입니다.

 

출처 : Android Developer

 

 

왼쪽 다이어그램이 startService() 로 서비스가 생성된 경우의 생명 주기이고, 오른쪽은 bindService() 로 서비스 생성된 경우의 생명 주기입니다.
bindService() 에 대해서는 다음에 작성해보겠습니다.

 

사용자 알림 닫기

Android 13 (API 33) 부터는 사용자가 기본적으로 포그라운드 서비스와 연결된 알림을 스와이프 동작을 실행해서 닫을 수 있습니다.

기존에는 포그라운드 서비스가 중지되거나 포그라운드에서 삭제되지 않는 한 알림이 해제되지 않았습니다.

 

사용자가 알림을 닫을 수 없도록 하려면, Notification.Builder 를 사용하여 알림을 만들 때 setOngoing(true) 를 설정하면 됩니다.

반응형