본문 바로가기

안드로이드/팁

TargetSdkApi 29 대응하기

반응형

이제 11월부면 신규앱도 구글 스토어에 등록할때 targetSdkApi를 29로 조정해야합니다. 등록하기 앞서 기존에 사용중이던 기능들이 제대로 작동하는지 파악해야합니다. 굵직한 변화들은 이미 많은분들이 포스팅을 통해 소개했기 때문에 실질적으로 마이그레이션시 신경써야 하는 부분들을 서술 하도록 하겠습니다. 

 

>> 비SDK 사용 금지

구글 문서에 공식화 되지 않은 SDK들로 강제로 사용하는 경우가 있다고 하네요. 생소해서 처음 들어보긴 하지만 blacklist(차단목록)에 포함된 인터페이스에 접근하려고 할때 에러가 발생할 수 있으니 사용중이라면 제거하고 출시하는게 맞을것 같아서 찾아 봤습니다. 

먼저 비 SDK API는 3가지로 구분됩니다. 

  • blacklist ( 차단 목록 ) - 앱의 타겟 api 수준과 상관없이 사용할 수 없는 비 sdk 인터페이스 
  • greylist-max-x ( 조건부 차단 ) 
  • greylist ( 지원되지 않음 ) 

사용중인지 체크하기

veridex도구를 이용하여 종류별로 체크합니다. mac os가 아니라면 공식 문서를 참고해서 진행해주세요

  • 도구 다운로드
  • appcompat.tar.gz 파일을 추출합니다.
  • 추출된 폴더에서 veridex-mac.zip 파일의 압축을 풉니다.
  • 압축이 풀린 위의 폴더 경로를 터미널로 이동한 후 다음 명령어를 실행합니다.
./appcompat.sh --dex-file=/path-from-root/your-app.apk

결과 확인

그레이 리스트는 검출됐지만 블랙리스트가 없어 실제 구동시 문제가 없어서 넘어가도 될것 같습니다.

>> 백그라운드 액티비티 시작 제한 

사용자에 대한 방해를 최소화 하고 잘 제어 하도록 하기 위해 백그라운드에서 Activity 시작을 제한합니다. 설령 포그라운드 서비스가 돌고 있다고 하더라도 앱이 onResume 상태가 아니면 시작할 수 없습니다. ( FLAG_ACTIVITY_NEW_TASK도 불가 ) 

구글에선 알림으로 대신 표시할것을 권고하나 명백히 엑티비티와 다르기 때문에 별로 땡기지 않는 방법입니다. FullScreenIntent를 이용하며 구현 방식은 공식 문서 참고 해주세요. 그외 엑티비티 시작이 가능한 경우를 서술해놨지만 targetsdkapi28 버전에서 바꿀 내용이 없었습니다. ( 경우에 따라 다를수 있으니 테스트는 필수로 진행해주세요. ) 

엑티비티 시작이 가능한 경우 ( 참고

  • 앱이 onResume 상태일 경우 ( 포그라운드에 실행되고 있는 경우 )
  • 알림 창에서 사용자가 앱의 알림을 직접 선택하여 액티비티가 시작되는 경우 
  • SYSTEM_ALERT_WINDOW 권한을 사용자로부터 부여받은 경우
    • 오레오 버전(O)부터 변경되어 TYPE_APPLICATION_OVERLAY 타입의 창을 띄우는 기능은 29버전에서도 동일하게 사용 가능합니다.
  • 앱의 엑티비티가 백스택에 남아 있는 경우 

>> 디바이스 고유 식별자 변경

디바이스 식별자를 수집해 다중 디바이스를 체크하는등 많은 부분에서 사용했었지만 이미 과거부터 막히기 시작해 많은 서비스에서 다른 방법을 사용하고 있을 것이며, 저희는 로그인한 시점을 시간으로 저장해 비교하는 방법을 사용했습니다. 혹시 사용중이신게 아래 목록중 있으시다면 대체 코드를 작성하셔야 합니다.

TelephonyManager 

  • getDeviceId() : null
  • getImei() : null
  • -etMeid() : null

Build

  • getSerial() : unknown 
  • SERIAL : unknown

WifiInfo

  • getMackAddress() : 02:00:00:00:00:00 

권고하고 있는 대체안으론 광고 ID SSAID, 권장사항을 참고해 구현해주세요. 

  • 광고 ID 수명 : 디바이스 초기화 및 광고 ID 초기화
  • SSAID 수명 : 디바이스 초기화 

>> Scoped Storage

target 29 버전부터 내 외부 저장소 개념을 다르게 도입해 차별화되게 관리하지만 아직 적용 단계에 있어 불안정하여 우회 코드를 사용하여 처리하면 이전 버전에 적용됐던 코드들이 문제 없이 작동합니다. 하지만 추후 30 이상에 버전엔 조금 더 강력해질 수 있으니 주의해야 합니다. 

AndroidManifest.xml

    <application
       .....
        android:requestLegacyExternalStorage="true" > 

>> 새로운 기기 위치 접근 권한 

앱을 사용하다 보셨을텐데 위치 권한을 허용할때 '앱 사용 중에만 허용' 이 새로 생겼습니다. 기존에는 2가지 권한만 추가해서 요청 했으면 됐지만 targetsdk29로 변경하면 백그라운드에서 위치를 허용할건지 추가해야합니다 . 자세한 사항은 해당 포스팅을 확인해주세요. 

contentResolver.query sql문 사용 금지

사진첩 앨범가져올때 DISTICN를 이용해 중복제거된 값을 받아 오는데, 쿼리문을 사용하면 안되서 map을 통해 직접 중복 제거를 해야합니다. ( 관련 링크 )

기존코드

        val projection = arrayOf("DISTINCT " + MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
        val cursor = contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                null, null, null, sortOrder)

수정된 코드 

  	val cursor = contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                null, null, null, null)



	cursor?.let {
            it.moveToLast()

            var overlapCheck = HashSet<String>()
            var index = it.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
            while (it.moveToPrevious()) {
                var albumName = it.getString(index)
                if(!overlapCheck.contains(albumName)){
                    overlapCheck.add(albumName)
                    albumList!!.add(albumName)
                }

            }
        }
    

 

이후 발견되는 오류들이 생기면 추가하도록 하겠습니다.

 

 

반응형