개발린생

[Android/Google Play] 포그라운드 서비스 권한 관련 거부 사유 및 해결 방법 (with WorkManager) 본문

너와 나의 문제 ・⋆。✰

[Android/Google Play] 포그라운드 서비스 권한 관련 거부 사유 및 해결 방법 (with WorkManager)

김블루 2024. 12. 16. 22:35

앱 심사 제출 후 앱이 거부되었는데 앱 거부 사유에 적힌 문제는 총 세가지 였고, 문제들의 원인은 크게 하나였다.

 

본문 요약:

진행하는 프로젝트에서 푸시 알림을 받았을 때, 다른 앱 위에 특정 화면을 표시하기 위해 Foreground Service를 활용하여 기능을 구현했고, 이것이 구글 정책에 위반되어 Foreground Service가 아닌 WorkManager를 활용하여 기능을 구현하도록 변경했다.

 

주의사항:

내가 구현한 기능이 그렇다는거지 Foreground Service를 무조건 WorkManager로 대체하라는 것이 아니다.

그냥 기능마다 Foreground Service를 활용하는 것이 적합한지, WorkManager를 활용하는 것이 적합한지 다른 것이다.

아마 내가 구현한 기능도 무조건 Foreground Service로 구현하라는 것이 아니라, Foreground Service로 구현할 수 있지만 이것으로 구현할 것이라면 사용자가 앱이 실행중임을 알 수 있도록 표시하라는 것일거다. (해보진 않았지만 안내하는 내용이 그러함)


Google Play 앱 거부 사유

더보기

발견된 문제

  1. 발견된 문제: 서비스 중단 또는 기능 지연이 사용자에게 중요한 영향을 미치지 않음
    선언된 사용 사례 중 하나 이상이 포그라운드 서비스 권한의 사용 방식을 준수하지 않는 것으로 확인되었습니다. 특히 선언된 사용 사례는 부정적인 사용자 경험을 초래하지 않으면서 시스템에 의해 중단되거나 지연될 수 있습니다. 앱에서 필수사항이 아니지만 Remote Messaging - Other에 포그라운드 서비스를 사용하고 있습니다.
  2. 발견된 문제: 권한 사용이 선언되지 않았거나 잘못 선언됨
    앱에서 포그라운드 서비스 권한을 사용하는 하나 이상의 사용 사례가 잘못 제출되었거나 Console 선언에서 누락된 것으로 확인되었습니다.
    - Remote Messaging - Other 기능을 올바르지 않은 FGS 유형으로 잘못 선언했습니다.
  3. 발견된 문제: 사용자가 기능을 시작하지 않거나 기능을 인지할 수 없음
    선언된 사용 사례 중 하나 이상이 포그라운드 서비스 권한의 사용 방식을 준수하지 않는 것으로 확인되었습니다. 특히 사용자가 활성 상태일 때 권한이 필요한 기능을 알 수 없습니다. Remote Messaging - Other 기능을 실행할 때 사용자가 FGS 사용을 인지할 수 없습니다.

발견된 문제에 동일하게 기재된 내용

선언된 모든 사용 사례가 영향을 받는 경우 FOREGROUND_SERVICE 권한도 삭제해야 합니다.

포그라운드 서비스 권한 정보

포그라운드 서비스 권한은 사용자 대상 포그라운드 서비스가 적절히 작동하는 데 필요합니다. Android 14 이상을 타겟팅하는 앱의 경우 앱에 사용되는 포그라운드 서비스마다 유효한 포그라운드 서비스 유형을 지정하고 해당 유형에 적합한 포그라운드 서비스 권한을 선언해야 합니다. 예를 들어 앱의 사용 사례에서 지도 위치정보가 필요한 경우 앱의 매니페스트에서 FOREGROUND_SERVICE_LOCATION 권한을 선언해야 합니다.

systemExempted 및 shortService 포그라운드 서비스 유형을 제외하고, 포그라운드 서비스가 다음과 같이 사용되는 경우에만 앱에서 포그라운 서비스 권한을 선언할 수 있습니다.

  • 사용자에게 유용하며 앱의 핵심 기능과 관련이 있는 기능을 제공합니다.
  • 사용자가 포그라운드 서비스 사용을 시작하거나 인식할 수 있습니다(예: 노래 재생 소리, 다른 기기에 미디어 전송, 정확하고 명확한 사용자 알림, 사진을 클라우드에 업로드하기 위한 사용자 요청).
  • 사용자가 포그라운드 서비스 사용을 종료하거나 중단할 수 있습니다.
  • 부정적인 사용자 경험 또는 사용자가 예상한 기능의 오작동을 초래하는 경우를 제외하고 시스템에 의해 중단 또는 지연되어서는 안 됩니다(예: 전화 통화는 즉시 시작되어야 하고 시스템에 의해 지연되어서는 안 됨)
  • 작업을 완료하기 위해 필요한 만큼만 실행됩니다.

포그라운드 서비스 사용에 관한 자세한 내용은 이 Play Console 고객센터 페이지를 참고하세요.

 

문제의 원인은 Foreground Service가 필요없는 기능을 Foreground Service로 구현한 것.

뭐 어떻게보면 이전까지 Foreground Service로 구현하는게 맞았지만 지금으로써는 다른 방식으로 구현하게끔 보는게 맞을 것 같다.


Foreground Service로 구현한 기능

Foreground Service를 사용한 이유는 Android 앱에서 푸시 알림을 받을 때 특정 화면을 다른 앱 위에 표시하기 위함이었다.

 

지금 chatGPT에게 "안드로이드 앱에서 푸시 알림이 왔을때 다른 앱 위에 특정 화면을 표시하려면 어떻게 구현해?" 라고 물어보면

Foreground Service를 활용하여 구현하는 방법을 안내해주고, 심지어 여러 방법 중 Foreground Service를 사용하는 것을 추천해준다.

 

푸시 알림과 WorkManager의 관계

푸시 알림을 받았을 때 특정 화면을 표시하는 작업은 즉시 실행돼야하므로, WorkManager가 반드시 필요한 것은 아니다.

푸시 알림은 이미 FirebaseMessagingService에서 트리거되기 때문에 FirebaseMessagingService 내에서 직접 구현하거나 Foreground Service를 시작하는 것으로 충분할 수 있다.

하지만 앱이 완전히 종료된 상태에서도 작업을 보장해야하기 때문에 Foreground Service 또는 WorkManager가 필요하다.


왜 Foreground Service가 문제가 되는가

위 거부 사유를 보면 Foreground Service 사용이 Google Play 정책을 위반하고 있다고 한다.

  • 앱이 Remote Messaging(ex. FirebaseMessagingService)에서 포그라운드 서비스를 사용해야하는 이유가 있는지 다시 확인
  • Google Play 정책에 의하면 사용자가 포그라운드 서비스를 인지하고, 직접적으로 시작하거나 종료할 수 있도록 구현
    • 캐시워크, 틈틈봇 등 앱 실행 없이 기능을 제공하는 앱을 보면 서비스가 실행되고 있을 때 상단 알림바에 실행중인 앱이 표시되는 것을 볼 수 있음

위 사유를 고려하면 충분히 리젝 사유가 될 수 있다.

왜냐하면 나의 경우 Foreground Service를 적용하긴 했는데 상단 알림바에 서비스 실행중 표시를 안했기 때문이다.

 

해결 방법

여기서 내가 이해한 해결 방법은 두 가지다.

  1. Foreground Service로 기능을 구현하되, 서비스로 실행되는 경우 사용자가 앱이 실행되고 있음을 인지하고 직접 종료도 가능하게 앱 상단에 실행중 상태를 표시 
  2. WorkManager로 대체하여 구현

두 가지 방식이 있지만 구글에서는 Messaging 기능은 포그라운드 서비스 없이 WorkManager로 대체 구현할 수 있으니 이를 권장했다.

그리하여 난 WorkManager를 적용했다. 🧑‍⚖️


ForegroundService -> WorkManager 대체

나의 경우 푸시 알림이 수신됐을 때, 특정 화면이 다른 앱 위에서 실행되도록 구현해야한다.

그렇다면 아래 상태에서도 작업이 보장돼야한다.

  • 포그라운드 상태 - 현재 화면에 앱이 보이는 상태
  • 백그라운드 상태 - 현재 화면에 앱이 보이지 않지만 앱 서랍에 표시되는 상태
  • 앱 종료 상태 - 앱 서랍에서도 종료된 상태

WorkManager를 사용하는 경우:

  1. 장기 실행 작업이 필요한 경우
  2. 앱이 종료되거나 재시작된 경우에도 작업을 유지해야 하는 경우
  3. 작업 실행 조건이 있는 경우
  4. 정기적으로 반복 실행이 필요한 경우
  5. 백그라운드에서 실행되어야 하는 경우

내가 구현한 기능은 2, 5번에 해당된다.


WorkManager 호출 예시

WorkManager 적용 코드 중 일부이지만 끄적여보자면 호출 방식은 아래와 같다.

 

푸시 알림이 수신될 때 호출되는 onMessageReceived:

  • 메서드에서 입력된 데이터를 받아 WorkManager에 전달 
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        // 푸시 알림 데이터 처리
        val title = remoteMessage.notification?.title ?: "Default Title"
        val body = remoteMessage.notification?.body ?: "Default Body"

        // WorkManager를 통해 데이터 처리 요청
        val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
            .setInputData(
                workDataOf(
                    "title" to title,
                    "body" to body
                )
            )
            .build()

        WorkManager.getInstance(this).enqueue(workRequest)

        // 바로 알림 표시
        showNotification(title, body)
    }

    private fun showNotification(title: String, body: String) {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        val notification = NotificationCompat.Builder(this, "default_channel")
            .setContentTitle(title)
            .setContentText(body)
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build()

        notificationManager.notify(1, notification)
    }
}

 

 

WorkManager로 백그라운드 작업 수행:

  • WorkManager를 통해 푸시 알림과 함께 전달된 데이터를 처리
class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        val title = inputData.getString("title") ?: "Default Title"
        val body = inputData.getString("body") ?: "Default Body"

        // 서버 데이터 동기화 또는 로그 기록 등 백그라운드 작업 수행
        // TODO: ... 다른 앱 위에 표시할 화면 이동 처리 ?

        return Result.success()
    }
}

WorkManager 사용 시 주의사항

WorkManager는 앱이 종료되거나 디바이스가 재부팅되어도 작업이 유지된다.

하지만 작업 스케줄링의 특성상 즉각적으로 실행되지 않을 수 있으며, 즉각적인 실행이 보장돼야한다면 Foreground Service 사용을 고려해봐야한다. 채팅과 같은 실시간 작업도 해당된다.

그치만 즉각적인 실행을 위해서는 Foreground Service를 써라. 이것도 아니다..

Foreground Service의 경우 앱 종료 시 작업이 중단될 수 있다.

 

WorkManager와 Foreground Service 비교

기능마다 필요한 요구사항이 다 다르니 아래 표에서 제공하는 기능과 장단점을 잘 생각해보고 기능에 적용하면 좋을 것이다.

기능 WorkManager Foreground Service
적합한 작업 유형 장기 실행, 백그라운드 작업 실시간, 즉각적인 사용자 인지 작업
백그라운드 작업 보장 앱 종료 및 재부팅 후에도 작업 보장 앱 종료 시 작업 중단 가능
실행 조건 네트워크 상태, 배터리 상태 등 조건 설정 가능 조건 설정 불가
사용자 인지 작업이 사용자에게 보이지 않을 수 있음 알림을 통해 사용자에게 작업 실행을 명확히 알림
Google 정책 준수 정책 준수 쉬움 정책 위반 위험 존재