사이드프로젝트 slecs

Android 16 대응으로 입금 알림 캡처 앱 권한 구조 재설계

목차

Pay Monitor v2: 은행앱 입금 캡처 + SMS 전달 기능

Android 앱 쪽 작업이 생각보다 빡셌음. 특히 Android 16 타겟팅 대응이 핵심이었는데, targetSdkVersion을 올리면서 권한 처리 방식이 바뀐 부분이 있어서 꼼꼼히 체크해야 했음.

주요 변경 포인트

항목 변경 전 변경 후
targetSdk 34 35 (Android 16)
sysId 필드 없음 기기 식별자 추가
API 포맷 단순 JSON 구조화된 페이로드

sysId 필드는 서버 사이드에서 어느 기기에서 온 요청인지 트래킹하려고 추가했음. 초기엔 UUID를 쓰려다가 앱 설치당 고유하게 유지되어야 해서 SharedPreferences 기반으로 최초 설치 시 생성해서 저장하는 방식으로 구현함.

API 포맷 변경

// 변경 전
{ "msg": "입금 5,000원" }

// 변경 후
{
  "sysId": "abc-123",
  "type": "DEPOSIT",
  "amount": 5000,
  "msg": "입금 5,000원"
}

SetupActivity 개편

알림 권한 요청 플로우를 Android 13부터 강제된 POST_NOTIFICATIONS 기반으로 다시 짰음. 권한 없으면 리스너 서비스 자체를 시작 못하게 막아두고 UI에서 안내 메시지 노출하도록 처리함.

다음: 배터리 최적화 예외 처리 자동화 검토

NotificationListenerService 생명주기

알림 리스너 서비스는 시스템이 메모리 부족 시 종료시킬 수 있음.

class NotificationCollector : NotificationListenerService() {

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        val pkg = sbn.packageName
        if (isTargetApp(pkg)) {
            val text = sbn.notification.extras
                .getString(Notification.EXTRA_TEXT) ?: return
            processNotification(text)
        }
    }

    override fun onListenerDisconnected() {
        // 서비스 재연결 시도
        requestRebind(ComponentName(this, NotificationCollector::class.java))
    }
}

START_STICKY로 설정해도 Doze 모드에서는 제한이 있음. 사용자가 배터리 최적화 예외를 직접 허용해줘야 안정적으로 동작함.

댓글 0

첫 댓글 달아줘.