Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

배터리를 위한 위치 최적화

Android 8.0(API 레벨 26)에 백그라운드 위치 제한이 도입되면서 위치 서비스 사용이 배터리 소모에 미치는 영향이 다시 주목을 받게 되었습니다. 이 페이지에서는 일부 위치 서비스 권장사항을 소개하고 앱의 배터리 효율성을 높이기 위해 현재 취할 수 있는 조치에 대해 설명합니다. 이런 권장사항을 적용하면 실행되는 플랫폼 버전과 관계없이 도움이 됩니다.

Android 8.0에 도입된 백그라운드 위치 제한은 다음과 같은 변경사항이 있습니다.

  • 백그라운드 위치 수집이 제한되고 위치는 연산되어 1시간에 몇 번만 전달됩니다.
  • Wi-Fi 검색은 그 빈도가 더욱 적고, 기기가 동일한 고정 액세스 포인트에 연결되어 있을 때는 위치 업데이트가 연산되지 않습니다.
  • 지오펜싱 응답은 몇십 초에서 약 2분 간격으로 변경됩니다. 이번 변경으로 배터리 성능이 눈에 띄게 개선되었습니다. 일부 기기의 경우, 배터리 성능이 10배까지 향상되기도 합니다.

이 페이지에서는 더욱 정확도가 높고 프레임워크 위치 API보다 배터리에 대한 부담이 적은 Google 위치 서비스 API를 사용하는 것으로 가정합니다. 특히, 이 페이지에서는 가속도계, 자이로스코프, 자기계 및 기타 센서는 물론이고 GPS, Wi-Fi, 셀 네트워크의 신호를 결합하는 융합된 위치 제공자 API를 잘 알고 있는 것으로 가정합니다. 또한 융합된 위치 제공자 API 위에 빌드되고 배터리 성능에 최적화된 지오펜싱 API에 대해서도 숙지하고 있어야 합니다.

배터리 소모에 대한 이해

위치 정보 수집과 배터리 소모는 다음과 같은 측면에서 직접적인 관련이 있습니다.

  • 정확도: 위치 데이터의 정밀함. 일반적으로 정확도가 높을수록 배터리 소모가 큽니다.
  • 빈도: 위치 연산 빈도. 위치 연산 빈도가 높을수록 배터리를 더 많이 사용합니다.
  • 지연 시간: 위치 데이터의 제공 속도. 일반적으로 지연 시간이 적을수록 더 많은 배터리가 필요합니다.

정확도

setPriority() 메서드를 사용하여 다음 값 중 하나를 인수로 전달하면 위치 정확도를 지정할 수 있습니다.

  • PRIORITY_HIGH_ACCURACY는 가장 정확한 위치를 제공합니다. 위치 정보는 필요에 따라 여러 가지 입력값을 사용하여 연산되는데(GPS, Wi-Fi, 셀을 활성화하고 여러 종류의 센서 사용), 배터리를 상당히 소모할 수 있습니다.
  • PRIORITY_BALANCED_POWER_ACCURACY는 전력 사용을 최적화하면서도 정확한 위치를 제공합니다. GPS는 거의 사용하지 않습니다. 일반적으로 Wi-Fi와 셀 정보를 결합하여 기기 위치를 연산합니다.
  • PRIORITY_LOW_POWER는 대체로 무선 셀 기지국을 사용하고 GPS와 Wi-Fi 입력값은 사용하지 않기 때문에 배터리를 최소한으로 사용하는 조밀하지 않은(도시 수준) 정확도를 제공합니다.
  • PRIORITY_NO_POWER는 다른 앱에서 이미 연산되어 있는 위치 정보를 수동적으로 수신합니다.

대부분 앱에서 필요한 위치 정보는 균형 잡힌 전력 사용 또는 절전 옵션을 사용해도 제공할 수 있습니다. 포그라운드에서 실행되고 실시간 위치 업데이트가 필요한 앱(예: 매핑 앱)에만 높은 정확도를 사용해야 합니다.

빈도

위치 빈도는 두 가지 방법으로 지정할 수 있습니다.

  • setinterval() 메서드를 사용하여 앱을 위해 위치를 연산하는 간격을 지정합니다.
  • setFastestInterval()을 사용하여 다른 앱에서 연산된 위치를 수신하는 간격을 지정합니다.

setInterval()을 사용할 때는 최대한 큰 값을 전달해야 합니다. 이는 특히 백그라운드 위치 수집에 중요한데, 원치 않게 배터리 소모를 일으키는 원인이 되는 경우가 많습니다. 포그라운드 사용 사례에 몇 초 간격을 사용해야 합니다. Android 8.0에 도입된 백그라운드 위치 제한은 이러한 전략을 적용하지만, Android 7.0 이하 기기에도 이 전략을 적용하고자 노력해야 합니다.

지연 시간

setMaxWaitTime() 메서드를 사용하여 지연 시간을 지정할 수 있습니다. 일반적으로는 setInterval() 메서드에 지정된 간격보다 몇 배 큰 값을 전달합니다. 이 설정은 위치 정보 전달을 지연하고 여러 위치 업데이트를 일괄 전달할 수 있습니다. 이 두 가지 변경사항은 배터리 소모를 최소화하는 데 도움이 됩니다.

앱에서 즉시 위치 정보가 필요하지 않은 경우 setMaxWaitTime() 메서드에 최대한 큰 값을 전달하여 지연 시간을 늘리는 대신 더 많은 데이터를 제공하고 배터리 효율을 높여야 합니다.

지오펜스를 사용할 경우 앱은 setNotificationResponsiveness() 메서드에 큰 값을 전달하여 전력을 절약해야 합니다. 5분 이상의 값을 사용하는 것이 좋습니다.

위치 사용 사례

이 섹션에서는 일반적인 위치 수집 시나리오에 대해 설명하고 지오펜싱 및 융합된 위치 제공자 API를 최적으로 사용하는 방법을 추천합니다.

보이는 사용자 또는 포그라운드 업데이트

예: 지연 시간이 매우 적고 자주 정확하게 업데이트가 필요한 매핑 앱. 모든 업데이트가 포그라운드에서 발생합니다. 사용자가 Activity를 시작하면 위치 데이터가 사용되고 잠시 후 Activity가 정지됩니다.

setPriority() 메서드에 PRIORITY_HIGH_ACCURACY 또는 PRIORITY_BALANCED_POWER_ACCURACY 값을 사용합니다.

setInterval() 메서드에 지정되는 간격은 사용 사례에 따라 달라집니다. 실시간 시나리오의 경우, 이 값은 몇 초로 설정하고 그 외에 나머지 경우에는 몇 분으로 설정합니다(배터리 사용량을 최소화하려면 약 2분 이상으로 설정하는 것이 좋습니다).

기기의 위치 확인

예: 날씨 앱이 기기의 위치를 알고자 합니다.

getLastLocation() 메서드를 사용하면 가장 최근에 수집한 위치 정보를 반환합니다(매우 드물게 null이 될 수도 있습니다). 이 메서드는 간단하게 위치 정보를 얻는 수단을 제공하고 적극적으로 위치 업데이트를 요청하는 것과 관련된 비용이 발생하지 않습니다. isLocationAvailable() 메서드도 함께 사용합니다. getLastLocation()이 반환한 위치가 적절히 최신 상태이면 true를 반환합니다.

사용자가 특정 위치에 있을 때 업데이트 시작

예: 사용자가 직장, 집 또는 다른 위치에서 특정 거리에 있을 때 업데이트를 요청합니다.

융합된 위치 제공자 업데이트와 함께 지오펜싱을 사용합니다. 앱이 지오펜스 진입 트리거를 수신하면 업데이트를 요청하고 앱이 지오펜스 퇴장 트리거를 수신하면 업데이트를 삭제합니다. 이렇게 하면 사용자가 지정된 영역에 들어갈 때만 앱이 더욱 자세한 위치 업데이트를 받을 수 있습니다.

이 시나리오의 일반적 워크플로는 지오펜스 진입 시 알림을 띄우고, 사용자가 알림을 탭했을 때 업데이트를 요청하기 위한 코드가 포함된 Activity를 시작하는 것입니다.

사용자 Activity 상태에 따라 업데이트 시작

예: 사용자가 운전 중이거나 자전거를 타고 있을 때만 업데이트를 요청합니다.

융합된 위치 제공자 업데이트와 함께 Activity 인식 API를 사용합니다. 목표로 하는 Activity가 탐지되었을 때 업데이트를 요청하고 사용자가 해당 Activity의 실행을 멈추었을 때 업데이트를 삭제합니다.

이 사용 사례의 일반적인 워크플로는 Activity 탐지 시 알림을 띄우고, 사용자가 알림을 탭했을 때 업데이트를 요청하기 위한 코드가 포함된 Activity를 시작하는 것입니다.

지역과 연결된 장기 실행 백그라운드 위치 업데이트

예: 기기가 리테일러 근처에 들어갔을 때 알림을 받기를 원합니다.

이는 지오펜싱의 모범적인 사용 사례입니다. 이 사용 사례는 백그라운드 위치를 사용하는 것이 거의 확실하므로 addGeofences(GeofencingRequest, PendingIntent) 메서드를 사용합니다.

다음과 같은 구성 옵션을 설정해야 합니다.

  • 거주지 변경을 추적하고 있다면 setLoiteringDelay() 메서드를 사용하여 약 5분 이하의 값을 전달합니다.

  • setNotificationResponsiveness()를 사용하여 약 5분에 해당하는 값을 전달합니다. 그러나 앱의 응답이 더 지연되어도 괜찮다면 약 10분에 해당하는 값을 사용해도 됩니다.

앱은 한 번에 최대 100개의 지오펜스만 등록할 수 있습니다. 앱이 많은 리테일러 옵션을 추적하는 사용 사례의 경우, 앱이 넓은 지오펜스(도시 수준)를 등록하고 넓은 지오펜스 안에 있는 매장에 대해 좁은 범위의 지오펜스(도시 내 위치)를 동적으로 등록하는 것이 좋습니다. 사용자가 넓은 지오펜스에 들어가면 좁은 범위의 지오펜스를 추가할 수 있습니다. 사용자가 넓은 지오펜스에서 나오면 좁은 범위의 지오펜스를 삭제할 수 있습니다. 새로운 지역에서는 지오펜스를 다시 등록해야 합니다.

가시적 앱 구성요소가 없는 장기 실행 백그라운드 위치 업데이트

예: 위치를 수동적으로 추적하는 앱

가능하면 배터리 소모가 거의 발생하지 않는 PRIORITY_NO_POWER 옵션을 적용하여 setPriority() 메서드를 사용하세요. PRIORITY_NO_POWER를 사용할 수 없다면 PRIORITY_BALANCED_POWER_ACCURACYPRIORITY_LOW_POWER를 사용하되, 지속적인 백그라운드 작업에는 PRIORITY_HIGH_ACCURACY를 사용하세요. 이는 이 옵션의 배터리 소모가 상당하기 때문입니다.

더 많은 위치 데이터가 필요할 경우 setFastestInterval() 메서드를 호출하여 setInterval()에 전달했던 것보다 작은 값을 전달하면 수동적으로 위치 정보를 수집할 수 있습니다. 수동적 위치 정보 수집은 PRIORITY_NO_POWER 옵션과 결합하면 다른 앱에서 연산한 위치 정보를 추가 비용 없이 기회가 있을 때마다 제공받을 수 있습니다.

setMaxWaitTime() 메서드를 사용하여 지연 시간을 다소 추가하는 방법으로 빈도를 조절합니다. 예를 들어 setinterval() 메서드에 약 10분으로 값을 설정한다면 30~60분으로 값을 설정한 setMaxWaitTime()을 호출하는 것이 좋습니다. 이 옵션을 사용하면 앱에 위치 정보가 약 10분마다 연산되지만, 앱이 30~60분마다 활성화되어서 일부 위치 데이터를 일괄 업데이트로 제공합니다. 이 방법은 지연 시간을 적용하는 대신 더 많은 데이터를 제공하고 배터리 성능을 향상합니다.

사용자가 다른 앱과 상호작용하는 동안 높은 정확도로 자주 업데이트

예: 사용자가 화면을 끄거나 다른 앱을 열었을 때도 계속 작동하는 내비게이션 또는 피트니스 앱

포그라운드 서비스를 사용합니다. 앱에서 사용자 대신 리소스가 많이 소모되는 작업을 수행할 가능성이 있을 경우, 사용자에게 해당 작업이 권장사항이라는 것을 알립니다. 포그라운드 서비스는 지속적인 알림이 필요합니다. 자세한 내용은 알림 개요를 참조하세요.

위치 권장사항

이 섹션의 권장사항을 구현하면 앱의 배터리 사용량을 줄이는 데 도움이 됩니다.

위치 업데이트 삭제

불필요한 배터리 소모가 발생하는 일반적인 원인은 필요하지 않은 시점에 위치 업데이트를 삭제하지 못하는 데 있습니다. 예를 들어 Activity의 onStart() 또는 onResume() 수명 주기 메서드에 requestlocationUpdates()에 대한 호출이 포함되어 있지만, onPause() 또는 onStop() 수명 주기 메서드에 그에 상응하는 removeLocationUpdates()에 대한 호출이 포함되지 않았을 때 불필요한 배터리 소모가 발생할 수 있습니다.

수명 주기 인식 구성요소를 사용하면 앱에서 Activity의 수명 주기를 더욱 효율적으로 관리할 수 있습니다. 자세한 내용은 수명 주기 인식 구성요소로 수명 주기 처리를 참조하세요.

시간 초과 설정

배터리 소모로부터 기기를 보호하려면 위치 업데이트를 중단해야 할 시점에 적절한 시간 초과를 설정합니다. 이렇게 시간 초과를 설정하면 업데이트가 무한히 계속되지 않도록 하고, (가령 코드의 버그로 인해) 업데이트를 요청했지만 삭제되지 않은 시나리오에서 앱을 보호합니다.

융합된 위치 제공자 요청의 경우 setExpirationDuration()를 호출해서 시간 초과를 추가합니다. 이는 이 메서드를 마지막으로 호출한 시점 이후부터의 시간을 밀리초 단위로 나타내는 매개변수를 수신합니다. 또한 setExpirationTime()을 호출해도 시간 초과를 추가할 수 있습니다. 이는 시스템이 마지막으로 부팅된 시점 이후부터의 만료 시간을 밀리초 단위로 나타내는 매개변수를 수신합니다.

지오펜스 위치 요청에 시간 초과를 추가하려면 setExpirationDuration() 메서드를 호출합니다.

일괄 요청

포그라운드에서 실행되지 않는 모든 사용 사례는 여러 요청을 한 번에 일괄 처리합니다. setInterval() 메서드를 사용하여 위치를 연산하려는 간격을 지정할 수 있습니다. 그런 다음에는 setMaxWaitTime() 메서드를 사용하여 위치가 앱에 전달되는 간격을 설정합니다. setMaxWaitTime() 메서드에 전달하는 값은 setInterval() 메서드에 전달하는 값의 몇 배가 되어야 합니다. 예를 들어 다음과 같은 위치 요청을 고려하세요.

Kotlin

val request = LocationRequest()
request.setInterval(10 * 60 * 1000)
request.setMaxWaitTime(60 * 60 * 1000)

Java

LocationRequest request = new LocationRequest();
request.setInterval(10 * 60 * 1000);
request.setMaxWaitTime(60 * 60 * 1000);

이 경우, 위치는 약 10분마다 연산되고 대략 1시간마다 약 6개의 위치 데이터 포인트가 일괄 전달됩니다. 약 10분마다 위치 업데이트를 받지만 기기는 1시간 정도에 한 번씩만 활성화되므로 배터리를 아낄 수 있습니다.

수동적 위치 업데이트 사용

백그라운드 사용 사례에서는 위치 업데이트를 제한하는 것이 좋습니다. Android 8.0은 이러한 방법을 사용하지 못하게 제한하지만, 오래된 기기에서 실행되는 앱은 최대한 백그라운드 위치 업데이트를 제한하려고 노력해야 합니다.

앱이 백그라운드에 있을 때는 다른 앱이 포그라운드에서 위치 업데이트를 수시로 요청할 가능성이 있습니다. 위치 서비스는 이런 업데이트를 앱에 제공합니다. 위치 데이터를 전략적으로 사용하는 다음과 같은 위치 요청을 고려해보세요.

Kotlin

val request = LocationRequest()
request.setInterval(15 * 60 * 1000)
request.setFastestInterval(2 * 60 * 1000)

Java

LocationRequest request = new LocationRequest();
request.setInterval(15 * 60 * 1000);
request.setFastestInterval(2 * 60 * 1000);

이전의 예에서 앱에서 위치가 약 15분마다 연산되었습니다. 다른 앱이 위치를 요청하면 그 데이터가 최대 2분 간격으로 앱에 제공됩니다.

수동적으로 위치 정보를 수신하는 데는 배터리가 소모되지 않지만 위치 데이터를 수신했을 때 리소스가 많이 소모되는 CPU 또는 I/O 작업이 트리거되는 경우에는 더욱 신중을 기해야 합니다. 배터리 비용을 최소화하려면 setFastestInterval()에 지정된 간격이 너무 작아서는 안 됩니다.

이 페이지의 권고를 따르면 사용자 기기의 배터리 성능을 크게 개선할 수 있습니다. 사용자가 배터리를 소모하지 않는 앱을 삭제할 가능성이 적습니다.