개발자를 위한 안드로이드 Q #4
본 포스트는 새롭게 변경된 '기기 위치 접근 권한'을 다루며, 3월 14일 공개된 안드로이드 Q 베타 1 버전 기준으로 작성되었습니다. 이후, 정식 버전에서는 기능 및 API가 변경될 수 있으며, 기능에 관한 소감이나 의견은 개인적인 의견으로 회사의 공식 의견과는 다를 수 있습니다.
안드로이드 Q에서는 '앱 사용 중에만 허용' 옵션이 추가됩니다. 사용자가 이 옵션을 선택하면 앱이 포그라운드인 상태인 경우에만 위치 정보를 확인할 수 있습니다. 만일, 백그라운드에서 동작 중인 상항에서도 기기 위치 정보에 접근해야 한다면, 새로운 권한 모델에 맞게 앱 수정이 필요합니다. 만일, 포그라운드 서비스에서 위치 정보를 활용하고 있다면 새로 추가된 'location' 포그라운드 서비스 타입을 활용해야 합니다.
위치 정보 관련하여 사용자 옵션이 하나 추가되었습니다. 사용자는 '항상 허용', '앱 사용 중에만 허용', '거부' 세 가지 옵션 중 하나 (혹은 거부 및 다시 묻지 않음)를 선택할 수 있게 됩니다.
개발자 관점에서는 어떤 변화가 생긴 걸까요? 선택 가능한 옵션을 두 가지에서 세 가지로 늘리기 위해서는 플래그가 하나 더 필요합니다. 이를 위해 새로운 ACCESS_BACKGROUND_LOCATION 권한이 추가되었습니다. 이 권한은 ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION 권한이 있는 경우에만 적용되며, 권한 구분을 위한 추가 플래그로 적용됩니다.
ACCESS_BACKGROUND_LOCATION 권한만 허용하는 경우는 의미가 없으니 제외합니다. 기존 위치 권한이 있는 상태에서 ACCESS_BACKGROUND_LOCATION 권한을 추가로 갖는지 여부에 따라, '앱 사용 중에만 허용'과 '항상 허용' 옵션이 나뉘게 됩니다.
이 변경 사항은 타깃 SDK 버전과 관계없이 모두 적용됩니다. 타깃 버전이 Q 미만인 경우, 매니페스트 상에 디바이스 위치 관련 관한 이 선언되어 있다면 시스템에서 자동으로 ACCESS_BACKGROUND_LOCATION 권한을 추가합니다. 또한, 앱에서 해당 권한을 요청하는 경우 자동으로 ACCESS_BACKGROUND_LOCATION 권한을 함께 요청합니다. 다시 말해, Q 미만 버전을 타깃 하는 앱은 항상 사용자에게 세 가지 옵션을 제공합니다.
만일 기기 위치 접근 권한은 갖고 있지만, ACCESS_BACKGROUND_LOCATION 권한이 없다면 어떤 일이 일어날까요? 앱이 백그라운드일 때 기기 위치 관련 API들이 어떻게 동작하는지 간단히 테스트를 해보았습니다.
FusedLocationProviderClient - ACCESS_BACKGROUND_LOCATION 권한이 없는 경우, 앱이 백그라운드로 진입하면 위치 정보를 가져올 수 없습니다. LastLocation 정보의 위도, 경도 값이 모두 'null'로 반환됩니다.
GeofencingClient - ACCESS_BACKGROUND_LOCATION 권한이 없는 경우, 아예 Geofence 추가 자체가 실패합니다. Task 결과로 에러 코드가 GeofenceStatusCodes에 정의된 값이 아닌 의미 불명의 '13' 값을 반환합니다. 이 부분은 아마도 변경이 될 것 같네요.
TelephonyManager API들 - ACCESS_BACKGROUND_LOCATION 권한이 없는 경우, 기기 위치를 짐작할 수 있는 API는(getCellLocation, getAllCellInfo 등) 'null' 값을 리턴합니다. PhoneStateListener의 onCellLocationChanged 등 기기 위치를 추측할 수 있는 콜백은 호출되지 않는 것으로 확인됩니다.
WifiScan / Bluetooth Discovery API - ACCESS_BACKGROUND_LOCATION 권한이 없는 경우, 앱이 백그라운드로 진입하며면 startScan() / startDiscovery() 메서드가 false 값을 리턴합니다.
이 외에도 기기 위치 정보를 노출할 수 있는 Telephony, Bluetooth, Wi-Fi API 목록은 Android Q changes: Privacy appendix 문서를 참고하시면 좋을 것 같습니다. 몇 가지 확인해본 API의 동작을 봐도 그렇지만, 이 목록에 포함된 API는 ACCESS_BACKGROUND_LOCATION 권한 없이는 백그라운드 사용이 힘들 것으로 예상됩니다.
그럼 앱 개발자 입장에서, 안드로이드 Q 대응을 위해 어떤 작업이 필요할까요? 안드로이드 Q에서 기기 위치 권한을 사용하는 방법은 크게 세 가지로 나눌 수 있습니다. 각각의 경우, 어떻게 마이그레이션 할 수 있는지 간단히 살펴보겠습니다.
근처 맛집을 찾거나, 가까운 주유소를 찾는 등 사용자가 명시적으로 앱을 사용할 때만 (해당 앱이 사용자 포커스를 갖고 있는 중) 기기 위치 정보가 필요할 수 있습니다. 이 경우, 별다른 코드 변경 없이도 기본 동작에 문제가 없습니다. 다만 타깃 SDK가 Q 미만이라면, 시스템에서 ACCESS_BACKGROUND_LOCATION 권한을 자동으로 추가하게 되고, 결국 불필요한 '항상 허용' 옵션이 표시됩니다. 타깃 SDK를 Q로 올리면, ACCESS_BACKGROUND_LOCATION 권한을 완전히 제외할 수 있습니다. 사용자에게 '앱 사용 중에만 허용' 권한만 요청할 수 있고, 보다 나은 UX를 제공할 수 있습니다.
두 번째 시나리오는 내비게이션 앱의 길 안내 혹은 자기 위치 공유와 같이 사용자가 앱을 직접 사용하고 있지 않지만 (앱이 사용자 포커스를 갖고 있지 않지만), 지속적으로 사용자 위치를 확인해야 하는 경우입니다. 이런 경우, 포그라운드 서비스를 이용해 백그라운드 실행 및 위치 제한을 피할 수 있었습니다.
기본적으로 안드로이드 Q에서도 이 방법을 사용할 수 있지만, 포그라운드 서비스를 활용하는 방법에 약간의 변화가 생겼습니다. 너무 많은 앱들이 이런저런 이유로 포그라운드 서비스를 남용하는 것을 막기 위해, 대표 사용 사례에 따라 몇 가지 포그라운드 서비스 타입이 지정되었습니다. 그리고 서비스 타입으로 'location'이 포함된 경우에만, 포그라운드 서비스를 통해 기기 위치 정보를 확인할 수 있습니다. 다시 말해, 비록 코드 상의 큰 변화는 아니지만, 포그라운드 서비스에서 위치 정보를 확인하고 있다면, Q 마이그레이션을 위해 코드 수정 및 재배포가 필요할 수 있습니다.
포그라운드 서비스를 'location' 타입으로 지정했다면, 이제 이 서비스는 포그라운드 앱으로 간주됩니다. 따라서, 별다른 제약 없이 디바이스 위치 정보를 확인할 수 있습니다. 결국, 첫 번째 경우와 마찬가지로 별도로 ACCESS_BACKGROUND_LOCATION 권한을 요청할 필요가 없고, 사용자가 '앱 사용 중에만 허용' 옵션을 선택한 경우에도 앱이 정상적으로 동작합니다.
앞 선 두 가지 경우와는 달리 한 앱이 '띄엄띄엄' 사용자 위치 정보를 확인하는 경우가 있습니다. 대표적으로 지오펜싱(Geo-Fencing)을 적용해 위치 기반 광고를 제공하는 등의 서비스를 생각해볼 수 있겠네요. 사용자가 해당 서비스의 장점을 직접적으로 느낄 수 없다면, 'location' 타입의 포그라운드 서비스를 활용하기 쉽지 않습니다 (사용자가 강제로 앱을 종료할 수 있습니다). 이때, 사용자가 '앱 사용 중에만 허용' 옵션을 선택한 경우, 사용자가 앱을 떠나는 순간 (홈 화면으로 돌아가는 등) 위치 정보를 확인할 수 없고, 앱 동작이 멈출 수 있습니다.
이런 경우 ACCESS_BACKGROUND_LOCATION 권한을 추가로 요청해야 합니다. 기기 위치 권한은 있지만, 백그라운드 위치 권한이 없는 경우를 처리하는 별도의 로직을 구성하고, 권한이 필요한 이유를 잘 설명하는 UX를 준비해야 합니다. 참고로 ACCESS_BACKGROUND_LOCATION 권한을 추가 요청하는 경우 위 스샷 같은 팝업이 표시됩니다.
이 외에도, 기기 위치 정보 보호를 위해 두 가지 변경 사항이 예고되고 있습니다.
사진 내 위치 정보 제거 - 사진 EXIF 메타 데이터에 포함된 위치 정보가 제거됩니다. 만일 해당 정보가 필요한 경우, 추가적으로 ACCESS_MEDIA_LOCATION 권한을 요청해야 합니다. 단, 이 부분은 아직 구현이 정상적으로 이루어지지 않은 느낌입니다. 몇 가지 테스트를 해본 결과 기존 사진 관련 앱에서 큰 문제없이 사진 위치 정보를 읽어 올 수 있었습니다. 이후 출시될 베타 버전을 기다려봐야 할 것 같네요.
랜덤 MAC 주소 - 기존 안드로이드 P 버전에서는 개발자 옵션으로 제공되던 기능입니다. 아주 간단히 이야기하면, 접속하는 공유기(Wi-Fi Network)가 달라질 때마다 디바이스의 MAC 주소가 변경되는 기능입니다. MAC 주소가 변경됨으로, 서비스 제공자가 공유기에 연결된 디바이스 MAC 주소 기반으로 광범위하게 사용자 디바이스를 식별하거나 기기 위치 정보를 추적하는 것을 방지할 수 있습니다. 다만, 공유기 연결이 끊어졌다 다시 붙는 경우에도, 처음에 생성된 MAC 주소는 그대로 유지됩니다. 따라서, 공유기의 MAC 주소 기반 필터링 기능 등은 정상적으로 동작합니다.
지금 까지 기기 위치 정보를 더 잘 보호하기 위해 안드로이드 Q에서 변경된 부분을 살펴보았습니다. 사용자 위치 정보를 활용하는 앱의 경우, 구현 방식에 관계없이 최적의 사용자 경험을 위해 크고 작은 코드 변경이 필요한 만큼 잘 살펴보시면 좋을 것 같습니다.
개발자 주의가 예상되는 안드로이드 Q의 변경 사항을 정리해 '개발자를 위한 안드로이드 Q 정리'라는 브런치 매거진으로 발행하고 있습니다.
2. 새로운 외부 저장소 정책 - 'Scoped Storage'
3. 초기화할 수 없는 하드웨어 고유 식별자 사용 금지
4. 새로운 기기 위치 접근 권한 - '앱 사용 중 허가'
본 포스트를 포함 우선적으로 베타 1 버전에는 개발자들의 주의가 필요한 (그래서 무서운) 동작 변경 사항에 관해 주로 다루었습니다. 이후 베타 2 버전이 공개되면, 개발자 입장에서 재밌고 새롭게 적용해볼 만한 신기능에 관해서도 다루어 볼 예정입니다 (그런 게 있겠죠?). 그런 만큼, 안드로이드 Q 버전이 정식 출시될 때까지, '개발자를 위한 안드로이드 Q 정리 매거진'에 많은 관심 부탁드립니다 : )