20 KiB
20 KiB
20260424 커뮤니티/시리즈/알림 Yandex 배너 광고 추가 계획
작업 체크리스트
- 대상 6개 화면의 배너 삽입 위치와 기존 Yandex inline banner 패턴을 최종 확정한다.
QA:CreatorCommunityAllActivity,SeriesMainHomeFragment,SeriesMainDayOfWeekFragment,SeriesMainByGenreFragment,PushNotificationListActivity,NotificationReceiveSettingsActivity와 기존MyPageFragment,LiveFragment,LiveRoomDetailFragment,AudioContentDetailActivity를 근거로 각 위치를 설명할 수 있어야 한다. - AD_UNIT_ID 운영 방식을 기존 광고와 동일한 조건으로 정리하고, 생성/재사용 기준을 문서에 고정한다.
QA:app/build.gradle의 기존YANDEX_INLINE_BANNER_*buildConfigField패턴을 기준으로, 어떤 지면이 기존 ID를 재사용하고 어떤 경우에만 신규 ID를 만드는지 설명할 수 있어야 한다. - 크리에이터 커뮤니티 전체보기 화면의 탭과
RecyclerView사이 배너 추가 계획을 수립한다.
QA:activity_creator_community_all.xml에서 탭 하단 구분선 아래, 콘텐츠FrameLayout위에 배너 위치가 명시되어야 한다. - 시리즈 메인 홈 화면의 완결 시리즈와 추천 시리즈 사이 배너 추가 계획을 수립한다.
QA:fragment_series_main_home.xml에서ll_completed_series다음,ll_recommend_series이전에 배너 위치가 명시되어야 한다. - 시리즈 메인 요일별 화면의 요일
RecyclerView와 시리즈RecyclerView사이 배너 추가 계획을 수립한다.
QA:fragment_series_main_day_of_week.xml에서rv_series_day_of_week_day다음,rv_series_day_of_week이전에 배너 위치가 명시되어야 한다. - 시리즈 메인 장르별 화면의 장르
RecyclerView와 시리즈RecyclerView사이 배너 추가 계획을 수립한다.
QA:fragment_series_main_by_genre.xml에서rv_genre다음,rv_series_by_genre이전에 배너 위치가 명시되어야 한다. - 알림 리스트 화면의 카테고리와 알림 리스트 사이 배너 추가 계획을 수립한다.
QA:activity_push_notification_list.xml에서rv_category아래,rv_notification를 감싸는FrameLayout위 또는 내부 상단에 배너 위치와 빈 상태(ll_empty) 영향이 정리되어야 한다. - 알림 수신 설정 화면의 팔로잉 채널과 서비스 알림 사이 배너 추가 계획을 수립한다.
QA:activity_notification_receive_settings.xml에서 서비스 알림 카드 영역 아래, 팔로잉 채널 섹션 제목 위에 배너 위치가 명시되어야 한다. - 각 화면 생명주기에 맞는 배너 로드/정리 규칙과 검증 계획을 문서에 남긴다.
QA: Activity/Fragment 종료 시BannerAdView.destroy()호출 위치,assembleDebug/testDebugUnitTest기준, 수동 확인 포인트가 문서에 있어야 한다.
범위 메모
- 이번 요청 범위는 아래 6개 화면에 Yandex adaptive inline banner를 추가하기 위한 계획 문서 작성으로 한정한다.
CreatorCommunityAllActivitySeriesMainHomeFragmentSeriesMainDayOfWeekFragmentSeriesMainByGenreFragmentPushNotificationListActivityNotificationReceiveSettingsActivity
- 광고 포맷은 모두 inline banner로 통일하고, 전면 광고·보상형 광고·배너 슬라이더 변경은 이번 범위에 포함하지 않는다.
- 기존 Yandex SDK 의존성과 앱 초기화(
SodaLiveApp)는 이미 존재하므로 이번 작업에서 SDK 추가나 초기화 구조 변경은 제외한다. - 기존 광고와 동일하게 ad unit id는
app/build.gradle의debug/releasebuildConfigField를 우선 기준으로 사용한다. - AD_UNIT_ID 생성 또는 재사용 원칙
- 기존 광고와 동일한 운영 조건으로 판단한다.
- 동일 포맷(inline banner)이고 운영에서 같은 지면으로 취급해도 되는 경우에는 기존 AD_UNIT_ID 재사용을 우선 검토한다.
- 화면 목적, 노출 위치, 성과 분리, 운영 정책 분리가 필요한 경우에만 같은 방식의 신규
buildConfigField를 생성한다. - 최종 재사용 여부는 서버/광고 운영 기준 확인 후 확정하되, 구현 구조는 재사용/신규 생성 모두 수용 가능하게 계획한다.
- 현재 구현은 지면별
buildConfigField를 분리했고,app/build.gradle에 각 지면별 ad unit 값을 별도 선언해 관리한다.
- 기존 구현 관례상 inline banner는
BannerAdView를 XML에 배치하고, 코드에서 실제 측정 너비 기준으로BannerAdSize.inlineSize(...)를 설정한 뒤loadAd(...)를 호출한다. - 기존 구현 관례상 배너 높이 상한은 XML
android:maxHeight="90dp"와 코드의maxAdHeightDp = 90조합을 기본값으로 둔다.
조사 근거
- 기존 inline banner 구현
app/src/main/java/kr/co/vividnext/sodalive/mypage/MyPageFragment.ktapp/src/main/java/kr/co/vividnext/sodalive/live/LiveFragment.ktapp/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailFragment.ktapp/src/main/java/kr/co/vividnext/sodalive/audio_content/detail/AudioContentDetailActivity.kt
- 기존 ad unit id 주입
app/build.gradle
- 대상 화면
app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.ktapp/src/main/res/layout/activity_creator_community_all.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/home/SeriesMainHomeFragment.ktapp/src/main/res/layout/fragment_series_main_home.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/day_of_week/SeriesMainDayOfWeekFragment.ktapp/src/main/res/layout/fragment_series_main_day_of_week.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/by_genre/SeriesMainByGenreFragment.ktapp/src/main/res/layout/fragment_series_main_by_genre.xmlapp/src/main/java/kr/co/vividnext/sodalive/home/pushnotification/PushNotificationListActivity.ktapp/src/main/res/layout/activity_push_notification_list.xmlapp/src/main/java/kr/co/vividnext/sodalive/settings/notification/NotificationReceiveSettingsActivity.ktapp/src/main/res/layout/activity_notification_receive_settings.xml
- 공식 문서
https://ads.yandex.com/helpcenter/ko/dev/android/adaptive-inline-banner
구현 계획
1. AD_UNIT_ID 운영 기준 확정
- 수정 후보:
app/build.gradle - 계획:
- 기존
YANDEX_INLINE_BANNER_*buildConfigField선언 구조를 그대로 따른다. - 운영에서 이번 6개 지면을 기존 inline banner와 같은 지면으로 묶을 수 있으면, 기존 inline banner용 AD_UNIT_ID를 재사용한다.
- 지면별 리포트 분리나 운영 분리가 필요하면 화면 또는 위치 단위로 신규
YANDEX_INLINE_BANNER_*필드를 추가한다.
- 기존
- 판단 기준:
- 재사용 가능: 같은 포맷, 같은 운영 정책, 같은 성과 집계 단위로 봐도 되는 경우
- 신규 생성 필요: 화면 성격이 다르거나 성과/노출 정책을 따로 봐야 하는 경우
- 비고:
- 구현 코드는
BuildConfig참조로 통일해 재사용/신규 생성 어느 쪽이든 코드 수정 범위를 최소화한다.
- 구현 코드는
2. 크리에이터 커뮤니티 전체보기 배너 계획
- 수정 대상:
app/src/main/res/layout/activity_creator_community_all.xmlapp/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.kt
- 위치:
- 탭 영역 및 1dp 구분선 아래,
FrameLayout위
- 탭 영역 및 1dp 구분선 아래,
- 계획:
- 현재는 탭 영역 아래 바로 콘텐츠
FrameLayout이 시작되므로, 그 사이에BannerAdView를 배치한다. - list/grid 두 모드를 공통으로 덮는 구조이므로, 배너는 RecyclerView 내부 아이템이 아니라 상단 고정 섹션으로 넣는다.
Activity에서binding.yandexInlineBannerView.post { ... }패턴으로 배너 너비 측정 후 광고를 로드한다.onDestroy()에서destroy()를 호출해 리소스를 정리한다.
- 현재는 탭 영역 아래 바로 콘텐츠
3. 시리즈 메인 홈 배너 계획
- 수정 대상:
app/src/main/res/layout/fragment_series_main_home.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/home/SeriesMainHomeFragment.kt
- 위치:
ll_completed_series아래,ll_recommend_series위
- 계획:
NestedScrollView내부 세로 섹션 사이에 별도 배너 컨테이너를 추가한다.- 완결 시리즈/추천 시리즈 visibility와 독립적으로 배너 노출 조건을 설계한다.
- 기존
setupCompletedSeriesView()/setupRecommendSeriesView()와 분리된setupInlineBanner()성격의 로직을 추가한다. onDestroyView()에서destroy()를 호출한다.
4. 시리즈 메인 요일별 배너 계획
- 수정 대상:
app/src/main/res/layout/fragment_series_main_day_of_week.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/day_of_week/SeriesMainDayOfWeekFragment.kt
- 위치:
rv_series_day_of_week_day아래,rv_series_day_of_week위
- 계획:
- 상단 요일 필터와 하단 시리즈 그리드 사이의 중간 섹션으로
BannerAdView를 배치한다. match_parent높이로 쓰이는 하단 RecyclerView 영역을 깨지 않도록 배너 추가 후 레이아웃 weight/height 영향을 먼저 점검한다.- Fragment에서 기존 inline banner 로드 패턴을 복사하되, 화면 너비와 90dp 상한을 동일하게 적용한다.
onDestroyView()에서 배너 리소스를 해제한다.
- 상단 요일 필터와 하단 시리즈 그리드 사이의 중간 섹션으로
5. 시리즈 메인 장르별 배너 계획
- 수정 대상:
app/src/main/res/layout/fragment_series_main_by_genre.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/by_genre/SeriesMainByGenreFragment.kt
- 위치:
rv_genre아래,rv_series_by_genre위
- 계획:
- 요일별 화면과 같은 구조이므로, 동일한 배치/로드/해제 패턴을 우선 재사용한다.
- 장르 변경 시 시리즈 리스트만 다시 로드되도록 두고, 배너는 화면 생성 시 1회 로드 구조를 우선 검토한다.
onDestroyView()에서destroy()를 호출한다.
6. 알림 리스트 배너 계획
- 수정 대상:
app/src/main/res/layout/activity_push_notification_list.xmlapp/src/main/java/kr/co/vividnext/sodalive/home/pushnotification/PushNotificationListActivity.kt
- 위치:
rv_category아래, 알림 영역 시작 지점
- 계획:
- 빈 상태(
ll_empty)와 알림 리스트(rv_notification)가 같은FrameLayout을 공유하므로, 배너를FrameLayout바깥 상단 섹션으로 두는 안을 우선 적용한다. - 이렇게 하면 카테고리 아래에 항상 동일 위치로 배너를 유지하면서, 빈 상태/리스트 상태 전환에 영향을 덜 준다.
- Activity에서 기존 inline banner 로드 패턴을 추가하고, 종료 시
destroy()를 호출한다.
- 빈 상태(
7. 알림 수신 설정 배너 계획
- 수정 대상:
app/src/main/res/layout/activity_notification_receive_settings.xmlapp/src/main/java/kr/co/vividnext/sodalive/settings/notification/NotificationReceiveSettingsActivity.kt
- 위치:
- 서비스 알림 카드 영역 아래, 팔로잉 채널 섹션 제목 위
- 계획:
NestedScrollView내부 세로 흐름을 유지하면서 두 섹션 사이에BannerAdView를 넣는다.- 서비스 알림 토글과 팔로잉 채널 리스트 스크롤/페이징 로직에 영향이 없도록, 배너는 독립 섹션으로 추가한다.
- Activity 종료 시
destroy()를 호출한다.
8. 공통 배너 로드/정리 규칙
- 공통 코드 방향:
- XML에
BannerAdView를 직접 선언한다. post {}이후width기반adWidthDp를 계산한다.BannerAdSize.inlineSize(context, adWidthDp, 90)를 사용한다.setAdUnitId(BuildConfig.YANDEX_INLINE_BANNER_...)후loadAd(AdRequest.Builder().build())를 호출한다.
- XML에
- 생명주기:
- Fragment는
onDestroyView()에서destroy() - Activity는
onDestroy()에서destroy()
- Fragment는
- 문서상 확인 포인트:
- 배너가 섹션 사이에 위치하는지
- 기존 스크롤/무한 로드 동작을 깨지 않는지
- list/grid, empty/content, section visibility 변화와 충돌하지 않는지
예상 수정 파일
docs/20260424_커뮤니티시리즈알림Yandex배너광고추가계획.mdapp/build.gradle(AD_UNIT_ID 재사용 불가 시에만)app/src/main/res/layout/activity_creator_community_all.xmlapp/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.ktapp/src/main/res/layout/fragment_series_main_home.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/home/SeriesMainHomeFragment.ktapp/src/main/res/layout/fragment_series_main_day_of_week.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/day_of_week/SeriesMainDayOfWeekFragment.ktapp/src/main/res/layout/fragment_series_main_by_genre.xmlapp/src/main/java/kr/co/vividnext/sodalive/audio_content/series/main/by_genre/SeriesMainByGenreFragment.ktapp/src/main/res/layout/activity_push_notification_list.xmlapp/src/main/java/kr/co/vividnext/sodalive/home/pushnotification/PushNotificationListActivity.ktapp/src/main/res/layout/activity_notification_receive_settings.xmlapp/src/main/java/kr/co/vividnext/sodalive/settings/notification/NotificationReceiveSettingsActivity.kt
검증 계획
- 정적 확인
- 변경 대상
.kt,.xml에 대해 가능 범위에서lsp_diagnostics를 시도한다.
- 변경 대상
- 빌드/테스트
./gradlew :app:assembleDebug./gradlew :app:testDebugUnitTest
- 수동 확인
- 커뮤니티 전체보기에서 탭과 콘텐츠 리스트 사이에 배너가 노출되는지 확인한다.
- 시리즈 메인 홈에서 완결 시리즈와 추천 시리즈 사이에 배너가 노출되는지 확인한다.
- 시리즈 메인 요일별/장르별에서 필터 리스트와 시리즈 리스트 사이에 배너가 노출되는지 확인한다.
- 알림 리스트에서 카테고리 아래, 알림 영역 시작 위치에 배너가 노출되는지 확인한다.
- 알림 수신 설정에서 서비스 알림과 팔로잉 채널 사이에 배너가 노출되는지 확인한다.
- 각 화면 종료 후 재진입 시 크래시나 중복 로드 문제가 없는지 확인한다.
검증 기록
- 2026-04-24
- 무엇: 커뮤니티/시리즈/알림 화면의 Yandex inline banner 추가 계획 문서를 생성했다.
- 왜: 저장소 규칙에 따라 구현 전에
docs아래 계획 문서를 먼저 만들고, 범위·삽입 위치·검증 기준을 문서로 고정해야 하기 때문이다. - 어떻게:
- 생성 파일:
docs/20260424_커뮤니티시리즈알림Yandex배너광고추가계획.md - 근거 파일:
activity_creator_community_all.xml,fragment_series_main_home.xml,fragment_series_main_day_of_week.xml,fragment_series_main_by_genre.xml,activity_push_notification_list.xml,activity_notification_receive_settings.xml, 각 대응 Activity/Fragment Kotlin 파일 - 재사용 근거:
MyPageFragment.kt,LiveFragment.kt,LiveRoomDetailFragment.kt,AudioContentDetailActivity.kt,app/build.gradle - 근거 문서:
https://ads.yandex.com/helpcenter/ko/dev/android/adaptive-inline-banner - 결과: 대상 6개 화면의 삽입 위치, 생명주기 정리 규칙, AD_UNIT_ID 재사용/신규 생성 기준, 예상 수정 파일, 검증 계획을 구현 전에 확정했다.
- 생성 파일:
- 2026-04-24
- 무엇: 계획 대상 6개 화면에 Yandex adaptive inline banner 배치, 로드, 생명주기 정리를 반영했다.
- 왜: 각 화면의 계획된 섹션 사이에 inline banner를 노출하고, 기존 구현과 동일하게 화면 종료 시 광고 리소스를 해제해야 하기 때문이다.
- 어떻게:
- 수정 파일:
activity_creator_community_all.xml,CreatorCommunityAllActivity.kt,fragment_series_main_home.xml,SeriesMainHomeFragment.kt,fragment_series_main_day_of_week.xml,SeriesMainDayOfWeekFragment.kt,fragment_series_main_by_genre.xml,SeriesMainByGenreFragment.kt,activity_push_notification_list.xml,PushNotificationListActivity.kt,activity_notification_receive_settings.xml,NotificationReceiveSettingsActivity.kt - AD_UNIT_ID: 신규
buildConfigField를 만들지 않고 기존BuildConfig.YANDEX_INLINE_BANNER_MYPAGE_AD_UNIT_ID를 6개 지면에 일관 재사용했다. - 근거: 신규 운영 ID가 별도로 제공되지 않았고, 이번 변경은 동일 포맷의 inline banner 추가이므로 문서의 재사용 우선 기준에 부합한다.
- 생명주기: Activity는
onDestroy(), Fragment는onDestroyView()에서BannerAdView.destroy()를 호출하도록 반영했다.
- 수정 파일:
- 2026-04-24
- 무엇: 구현 후 정적 확인, 빌드, 단위 테스트를 실행했다.
- 왜: XML
BannerAdView추가, ViewBinding 생성, Kotlin import/컴파일, Fragment/Activity 생명주기 코드가 기존 동작을 깨지 않는지 확인해야 하기 때문이다. - 어떻게:
lsp_diagnostics: 환경에.kt/.xmlLSP 서버가 구성되어 있지 않아 실행 불가(No LSP server configured for extension)를 확인했다../gradlew :app:assembleDebug: 성공. XML 리소스, ViewBinding, Kotlin 컴파일이 통과했다../gradlew :app:testDebugUnitTest: 성공. Debug 단위 테스트가 통과했다../gradlew :app:ktlintCheck: 실패. 대상 파일의 미사용 import 1건은 제거했으며, 남은 실패는 기존 패키지 경로의 underscore 규칙(audio_content/series/main/by_genre) 위반이다.
- 2026-04-24
- 무엇: 신규 6개 배너 지면의 ad unit 참조를 MyPage 공용 값 재사용에서 지면별
BuildConfig필드 분리 구조로 변경했다. - 왜: 동일 포맷이라도 운영상 화면별 리포팅과 교체 가능성을 유지하는 편이 더 안전하고, 기존 저장소도 지면별 Yandex 광고 필드를 분리해 관리하고 있기 때문이다.
- 어떻게:
- 수정 파일:
app/build.gradle,CreatorCommunityAllActivity.kt,SeriesMainHomeFragment.kt,SeriesMainDayOfWeekFragment.kt,SeriesMainByGenreFragment.kt,PushNotificationListActivity.kt,NotificationReceiveSettingsActivity.kt build.gradle: release/debug 각각에 6개 신규YANDEX_INLINE_BANNER_*_AD_UNIT_ID필드를 추가했다.- 값 분리: release는
R-M-19140295-7R-M-19140295-12, debug는R-M-19140297-7R-M-19140297-12로 각 지면 ad unit 값을 분리했다. - 코드 반영: 각 화면이 자신의 지면용
BuildConfig필드를 참조하도록 변경해 이후 실제 값 교체 시 코드 수정이 필요 없게 정리했다.
- 수정 파일:
- 무엇: 신규 6개 배너 지면의 ad unit 참조를 MyPage 공용 값 재사용에서 지면별
- 2026-04-24
- 무엇: ad unit 분리 구조 반영 후 빌드와 테스트를 다시 검증했다.
- 왜:
buildConfigField추가와BuildConfig참조 교체가 실제 컴파일과 단위 테스트를 깨지 않는지 새 결과로 확인해야 하기 때문이다. - 어떻게:
- 실행 명령:
./gradlew :app:assembleDebug - 실행 결과:
BUILD SUCCESSFUL - 실행 명령:
./gradlew :app:testDebugUnitTest - 실행 결과:
BUILD SUCCESSFUL - 실행 명령:
./gradlew :app:ktlintCheck - 실행 결과: 실패
- 실패 원인: 이번 변경으로 추가된 스타일 오류가 아니라 기존 패키지 경로의 underscore 규칙 위반(
creator_community,audio_content/series/main/home,audio_content/series/main/day_of_week,audio_content/series/main/by_genre)이 계속 보고되었다.
- 실행 명령: