📌 오르다 다이어리 레거시 리팩토링 02 - targetSdk 34 적용 이슈와 해결
최근 3년 전 개발한 레거시 프로젝트를 리팩토링하면서 targetSdkVersion을 32에서 34로 변경해야 하는 상황에 직면했다.

🛠 왜 Target SDK를 34로 올려야 했을까?
처음에는 targetSdkVersion 32로 유지하면서 UI 상태 관리 및 아키텍처 리팩토링을 진행하려 했으나, 아래와 같은 고민이 있었다.
- Google Play에 출시해보고 싶어질 수도 있고
- 최신 Android 보안 정책을 반영해야 하며
- 다른 라이브러리 사용할 때의 확장성을 고려해야 했기 때문
- 또한, 현재 사용자인 나의 핸드폰이 Anroid 14ㅇ이다.
결과적으로 최신 정책을 준수하는 것이 장기적으로 유지보수와 배포를 고려했을 때 더 나은 선택이라 판단했다.
그러나 targetSdk를 34로 변경하자마자 Android Studio에서 다양한 권한 정책 변경과 보안 강화로 인해 일부 기능이 정상 동작하지 않음을 알리는 경고 메시지가 발생했다.
😱 Configuration Change만 안되던 모든 기능들이 삐그덕 거리며 정상 동작하지 않기 시작했다.
오르다 다이어리는 내 프로젝트 중에서도 가장 다양한 권한을 요청하는 앱이었기에, 이를 해결하기 위해 SDK 버전별 정책을 하나하나 살펴보는 과정이 필요했다.
🔹 targetSdkVersion이란?
targetSdkVersion은 Android 시스템이 앱을 실행할 때 어떤 버전의 동작 방식을 따를지를 결정하는 값이다.
새로운 Android 버전이 출시되면서, 보안과 성능 향상을 위한 변경 사항이 추가되며, targetSdkVersion이 낮으면 최신 기능을 사용할 수 없거나 새로운 정책이 적용되지 않는다.
즉, 최신 SDK 버전으로 올리면 새로운 보안 정책과 권한 변경 사항을 준수해야 한다.
💡 Target SDK 34 적용 시 발생한 문제들
1️⃣ 권한 요청 관련 변경 사항
Android 13(API 33) 및 14(API 34)에서는 기존의 READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE 권한이 동작하지 않고, 새로운 미디어 접근 권한을 사용해야 한다.
기존에는 READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE로 모든 갤러리에 접근 가능했지만,
- Android 14(API 34)부터는 사용자가 선택한 사진만 접근할 수 있도록 Photo Picker 사용이 권장된다.
그래서 API 33 이상에서는 Photo Picker를 사용하고, API 32 이하에서는 기존 방식 유지하도록 했다.
참고: https://support.google.com/googleplay/android-developer/answer/14115180?hl=ko
✅ 결정 사항:
- 기존 READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE 대신 Photo Picker 사용
- API 32 이하는 기존 권한을 유지하도록 maxSdkVersion="32" 설정
2️⃣ 알람 설정 (AlarmManager) 이슈
Android 12(API 31) 이상에서는 정확한 시간(Exact) 알람을 설정할 때 추가적인 권한이 필요하게 변경되었다.
기존에는 권한 없이 AlarmManager.setExact()를 호출했으나,
👉 SCHEDULE_EXACT_ALARM 권한을 추가해야 정상 작동.
📌 공식 문서 참고:
출처: AlarmManager API 변경 사항 (Android 개발 문서)
Android 12 이상에서는 정확한 알람을 설정하려면 SCHEDULE_EXACT_ALARM 또는 USE_EXACT_ALARM 권한이 필요합니다.
단, USE_EXACT_ALARM은 시스템 앱에서만 사용 가능하므로, 일반 앱에서는 SCHEDULE_EXACT_ALARM을 추가해야 합니다.
✅ 결정 사항:
- SCHEDULE_EXACT_ALARM 권한 추가
3️⃣ PendingIntent의 FLAG 변경
Android 12(API 31) 이상에서는
PendingIntent를 생성할 때 FLAG_IMMUTABLE 또는 FLAG_MUTABLE을 반드시 명시해야 한다.
이전 코드에서는 PendingIntent.FLAG_UPDATE_CURRENT 만 사용했으므로 앱이 충돌하는 원인이 된다.
📌 공식 문서 참고:
출처: https://developer.android.com/reference/android/app/PendingIntent
Android 12(API 31) 이상에서는 모든 PendingIntent가 FLAG_IMMUTABLE 또는 FLAG_MUTABLE을 포함해야 합니다.
그렇지 않으면 앱이 충돌하거나 보안 문제로 인해 거부될 수 있습니다.
다른 참고 블로그:
https://itstory1592.tistory.com/127
✅ 결정 사항:
- PendingIntent 생성 시 FLAG_IMMUTABLE 또는 FLAG_MUTABLE 추가
📌 Target SDK 34 적용을 위한 주요 변경 사항 정리
변경 사항 설명
| Photo Picker 적용 | READ_MEDIA_IMAGES, READ_MEDIA_VIDEO API 33+에서 요청하나, 사진 선택 1개라 권장되는 Photo Picker 적용 |
| 알림 권한 POST_NOTIFICATIONS 추가 | API 33+에서만 요청하도록 변경 |
| Android 32 이하의 저장소 권한 유지 | maxSdkVersion="32"를 통해 API 32 이하에서만 기존 권한 사용 |
| 불필요 권한 삭제 (READ_MEDIA_AUDIO) | 사용되지 않던 READ_MEDIA_AUDIO 권한 제거 |
✅ 마무리 및 느낀 점
이번 리팩토링을 하면서 targetSdk를 높이는 과정에서 SDK 버전별 정책을 유지하면서 새로운 정책을 반영하는 과정의 중요성을 직접 경험했다.
사실, 나는 아직 서비스를 출시해 본 경험이 없었기 때문에 이런 버전 업과 정책 대응을 경험할 기회가 있을까 싶었다.
그러나 이번에 targetSdk를 올리는 과정에서 버전별로 이전 기능을 유지하면서도 새로운 정책에 맞게 설정하는 과정이 필수적임을 배웠다.
특히,
- 구버전(Android 31 이하)에서는 기존의 권한 방식 유지
- 신버전(Android 33 이상)에서는 최신 보안 정책에 맞게 Photo Picker 등 새로운 API 적용
- 정확한 알람 설정, PendingIntent 보안 정책 대응
이 모든 것이 버전별 대응 전략을 갖추는 것이 얼마나 중요한지를 깨닫게 한 경험이었다.
아직도 리팩토링할 부분은 많지만, 이번 작업을 통해 Android 버전별 정책을 꾸준히 살펴보는 것이 얼마나 중요한지 다시금 실감했다.
앞으로도 이런 변화를 꾸준히 학습하고 적용해나가면서 더욱 안정적인 앱을 개발할 수 있도록 노력해야겠다!
🔥 다음 목표
✅ Navigation Component 적용 & Single Activity 구조로 전환
✅ UI 상태 관리
🎯 결론: SDK 업데이트, 어렵지만 성장하는 기회였다!
처음에는 targetSdk 34로 올리는 것이 불필요한 복잡성을 초래하는 것 아닌가 고민했지만,
👉 장기적인 유지보수와 확장성을 위해 필수적인 과정이라는 점을 실감했다.
이 경험을 바탕으로 앞으로도 Android 정책 변화를 지속적으로 모니터링하고, 유지보수 및 개선에 신경 써야겠다고 다짐했다.
'Android > 오르다 다이어리' 카테고리의 다른 글
| [Android/오르다 다이어리] 레거시 리팩토링 05 - Configuration Change 대응 (ViewModel 적용) (0) | 2025.03.01 |
|---|---|
| [Android/오르다 다이어리] 레거시 리팩토링 04 - Fragment 마이그레이션 (0) | 2025.02.24 |
| [Android/오르다 다이어리] 레거시 리팩토링 03 - Navigation Component 적용 (0) | 2025.02.20 |
| [Android/오르다] 오르다 다이어리 레거시 리팩토링 01 - 현재 코드 분석 (0) | 2025.02.11 |
| [Android/오르다] 오르다 다이어리 레거시 리팩토링 00 - 계획 수립 (0) | 2025.02.10 |