지오펜싱은 현재 위치에 관한 사용자의 인식과 관심 위치에 관한 사용자의 근접성 인식을 결합합니다. 관심 위치를 표시하려면 위도와 경도를 지정합니다. 위치 근접성을 조정하려면 반경을 추가합니다. 위도와 경도, 반경은 지오펜싱을 정의하고 관심 위치 주위에 원형 영역 또는 펜스를 만듭니다.
기기 사용자당 앱별로 100개 제한으로 여러 활성 지오펜싱을 사용할 수 있습니다. 각 지오펜싱에서 위치 서비스에 방문 및 이탈 이벤트를 전송하도록 요청하거나 이벤트를 트리거하기 전에 지오펜싱 영역 내에서 대기하거나 머무를 시간을 지정할 수 있습니다. 만료 시간을 밀리초로 지정하여 지오펜싱 시간을 제한할 수 있습니다. 지오펜싱이 만료되면 위치 서비스에서 자동으로 삭제됩니다.
이 과정에서는 지오펜싱을 추가 및 삭제한 다음 BroadcastReceiver 를 사용하여 지오펜싱 전환을 수신 대기하는 방법을 보여줍니다.
지오펜싱 모니터링 설정
지오펜싱 모니터링을 요청하는 첫 번째 단계는 필요한 권한을 요청하는 것입니다. 지오펜싱을 사용하려면 앱에서 다음을 요청해야 합니다.
ACCESS_FINE_LOCATION
ACCESS_BACKGROUND_LOCATION 앱에서 Android 10(API 수준 29) 이상을 타겟팅하는 경우
자세한 내용은 위치 정보 액세스 권한 요청 방법에 관한 가이드를 참고하세요.
BroadcastReceiver 를 사용하여 지오펜싱 전환을 수신 대기하려면 서비스 이름을 지정하는 요소를 추가합니다. 이 요소는 요소의 하위 요소여야 합니다.
…
Location API에 액세스하려면 지오펜싱 클라이언트의 인스턴스를 만들어야 합니다. 클라이언트를 연결하는 방법을 알아보려면 다음을 참조하세요.
Kotlin lateinit var geofencingClient: GeofencingClient override fun onCreate(savedInstanceState: Bundle?) { // … geofencingClient = LocationServices.getGeofencingClient(this) } 자바 private GeofencingClient geofencingClient; @Override public void onCreate(Bundle savedInstanceState) { // … geofencingClient = LocationServices.getGeofencingClient(this); }
지오펜싱 만들기 및 추가하기
지오펜싱 객체를 만드는 데는 Location API 빌더 클래스를, 추가하는 데는 편의 클래스를 사용하여 앱에서 지오펜싱을 만들고 추가해야 합니다. 또한 지오펜싱 전환이 발생할 때 위치 서비스에서 전송된 인텐트를 처리하려면 이 섹션에 설명된 대로 PendingIntent 를 정의하면 됩니다.
참고: 단일 사용자 기기에서는 앱당 지오펜싱이 100개로 제한됩니다. 멀티 사용자 기기에서는 기기 사용자당 앱별로 지오펜싱이 100개로 제한됩니다.
지오펜싱 객체 만들기
먼저 Geofence.Builder 를 사용하여 지오펜싱을 만들어 원하는 지오펜싱의 반경과 지속 시간, 전환 유형을 설정합니다. 예를 들어 목록 객체를 채우려면 다음을 참조하세요.
Kotlin geofenceList.add(Geofence.Builder() // Set the request ID of the geofence. This is a string to identify this // geofence. .setRequestId(entry.key) // Set the circular region of this geofence. .setCircularRegion( entry.value.latitude, entry.value.longitude, Constants.GEOFENCE_RADIUS_IN_METERS ) // Set the expiration duration of the geofence. This geofence gets automatically // removed after this period of time. .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) // Set the transition types of interest. Alerts are only generated for these // transition. We track entry and exit transitions in this sample. .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT) // Create the geofence. .build()) 자바 geofenceList.add(new Geofence.Builder() // Set the request ID of the geofence. This is a string to identify this // geofence. .setRequestId(entry.getKey()) .setCircularRegion( entry.getValue().latitude, entry.getValue().longitude, Constants.GEOFENCE_RADIUS_IN_METERS ) .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) .build());
이 예에서는 데이터를 상수 파일에서 가져옵니다. 실제로는 앱에서 사용자 위치에 기반해 동적으로 지오펜싱을 만들 수 있습니다.
지오펜싱 및 초기 트리거 지정
다음 스니펫은 GeofencingRequest 클래스와 이에 중첩된 GeofencingRequestBuilder 클래스를 사용하여 모니터링할 지오펜싱을 지정하고 관련 지오펜싱 이벤트가 트리거되는 방법을 설정합니다.
Kotlin private fun getGeofencingRequest(): GeofencingRequest { return GeofencingRequest.Builder().apply { setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER) addGeofences(geofenceList) }.build() } 자바 private GeofencingRequest getGeofencingRequest() { GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); builder.addGeofences(geofenceList); return builder.build(); }
이 예에서는 두 개의 지오펜싱 트리거 사용법을 보여줍니다. 기기가 지오펜싱에 들어갈 때 GEOFENCE_TRANSITION_ENTER 전환이 트리거되고 기기가 지오펜싱에서 나갈 때 GEOFENCE_TRANSITION_EXIT 전환이 트리거됩니다. INITIAL_TRIGGER_ENTER 를 지정하면 기기가 이미 지오펜싱 내에 있는 경우 GEOFENCE_TRANSITION_ENTER 를 트리거해야 한다고 위치 서비스에 알립니다.
대부분의 경우 INITIAL_TRIGGER_DWELL 을 대신 사용하여 사용자가 지오펜싱 내에서 정의된 시간 동안 정지할 때만 이벤트를 트리거하는 것이 좋을 수 있습니다. 이 방법으로 기기가 지오펜싱에 잠시 들어가고 나올 때 발생하는 많은 알림으로 생기는 ‘알림 스팸’을 줄일 수 있습니다. 지오펜싱에서 최상의 결과를 얻는 또 다른 전략은 최소 반경을 100미터로 설정하는 것입니다. 이렇게 하면 일반적인 Wi-Fi 네트워크의 위치 정확성을 설명하고 기기 전력 소비를 줄이는 데 도움이 됩니다.
지오펜싱 전환을 위한 broadcast receiver 정의
위치 서비스에서 전송된 Intent 로 앱에서 다양한 작업을 트리거할 수 있지만 활동이나 프래그먼트를 시작해서는 안 됩니다. 구성요소가 사용자 작업에 응답해서만 표시되기 때문입니다. 대부분의 경우 BroadcastReceiver 는 지오펜싱 전환을 처리하는 좋은 방법입니다. BroadcastReceiver 는 지오펜싱으로 들어가는 또는 지오펜싱에서 나오는 전환과 같은 이벤트가 발생할 때 업데이트되므로 장기 실행 백그라운드 작업을 시작할 수 있습니다.
다음 스니펫은 BroadcastReceiver 를 시작하는 PendingIntent 를 정의하는 방법을 보여줍니다.
Kotlin class MainActivity : AppCompatActivity() { // … private val geofencePendingIntent: PendingIntent by lazy { val intent = Intent(this, GeofenceBroadcastReceiver::class.java) // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling // addGeofences() and removeGeofences(). PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) } } 자바 public class MainActivity extends AppCompatActivity { // … private PendingIntent getGeofencePendingIntent() { // Reuse the PendingIntent if we already have it. if (geofencePendingIntent != null) { return geofencePendingIntent; } Intent intent = new Intent(this, GeofenceBroadcastReceiver.class); // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when // calling addGeofences() and removeGeofences(). geofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent. FLAG_UPDATE_CURRENT); return geofencePendingIntent; }
지오펜싱 추가
지오펜싱을 추가하려면 GeofencingClient.addGeofences() 메서드를 사용합니다. GeofencingRequest 객체와 PendingIntent 를 제공합니다. 다음 스니펫은 결과 처리를 보여줍니다.
Kotlin geofencingClient?.addGeofences(getGeofencingRequest(), geofencePendingIntent)?.run { addOnSuccessListener { // Geofences added // … } addOnFailureListener { // Failed to add geofences // … } } 자바 geofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent()) .addOnSuccessListener(this, new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { // Geofences added // … } }) .addOnFailureListener(this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Failed to add geofences // … } });
지오펜싱 전환 처리
위치 서비스에서 사용자가 지오펜싱에 들어가거나 나온 것을 감지하면 개발자가 지오펜싱 추가 요청에서 포함한 PendingIntent 에 포함된 Intent 를 전송합니다. GeofenceBroadcastReceiver 와 같은 broadcast receiver는 Intent 가 호출된 것을 알아채고 나면 인텐트에서 지오펜싱 이벤트를 가져오고 지오펜싱 전환 유형을 확인하며 정의된 지오펜싱 중에 트리거된 것을 판단할 수 있습니다. broadcast receiver는 앱에서 백그라운드 작업 실행을 시작하도록 하거나 원하는 경우 알림을 출력으로 전송할 수 있습니다.
참고: Android 8.0(API 수준 26) 이상에서 지오펜싱을 모니터링하는 동안 앱이 백그라운드에서 실행되고 있다면 기기에서 2분마다 지오펜싱 이벤트에 응답합니다. 이러한 응답 제한에 앱을 맞추는 방법을 알아보려면 백그라운드 위치 제한을 참조하세요.
다음 스니펫은 지오펜싱 전환이 발생할 때 알림을 게시하는 BroadcastReceiver 정의 방법을 보여줍니다. 사용자가 알림을 클릭하면 앱의 기본 활동이 표시됩니다.
Kotlin class GeofenceBroadcastReceiver : BroadcastReceiver() { // … override fun onReceive(context: Context?, intent: Intent?) { val geofencingEvent = GeofencingEvent.fromIntent(intent) if (geofencingEvent.hasError()) { val errorMessage = GeofenceStatusCodes .getStatusCodeString(geofencingEvent.errorCode) Log.e(TAG, errorMessage) return } // Get the transition type. val geofenceTransition = geofencingEvent.geofenceTransition // Test that the reported transition was of interest. if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER | geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { // Get the geofences that were triggered. A single event can trigger // multiple geofences. val triggeringGeofences = geofencingEvent.triggeringGeofences // Get the transition details as a String. val geofenceTransitionDetails = getGeofenceTransitionDetails( this, geofenceTransition, triggeringGeofences ) // Send notification and log the transition details. sendNotification(geofenceTransitionDetails) Log.i(TAG, geofenceTransitionDetails) } else { // Log the error. Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)) } } } 자바 public class GeofenceBroadcastReceiver extends BroadcastReceiver { // … protected void onReceive(Context context, Intent intent) { GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); if (geofencingEvent.hasError()) { String errorMessage = GeofenceStatusCodes .getStatusCodeString(geofencingEvent.getErrorCode()); Log.e(TAG, errorMessage); return; } // Get the transition type. int geofenceTransition = geofencingEvent.getGeofenceTransition(); // Test that the reported transition was of interest. if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { // Get the geofences that were triggered. A single event can trigger // multiple geofences. List triggeringGeofences = geofencingEvent.getTriggeringGeofences(); // Get the transition details as a String. String geofenceTransitionDetails = getGeofenceTransitionDetails( this, geofenceTransition, triggeringGeofences ); // Send notification and log the transition details. sendNotification(geofenceTransitionDetails); Log.i(TAG, geofenceTransitionDetails); } else { // Log the error. Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)); } } }
PendingIntent 를 통해 전환 이벤트를 감지한 후 BroadcastReceiver 는 지오펜싱 전환 유형을 가져오고 앱이 알림(이 경우 GEOFENCE_TRANSITION_ENTER 또는 GEOFENCE_TRANSITION_EXIT )을 트리거하려고 사용하는 이벤트 중 하나인지 테스트합니다. 그런 다음 서비스는 알림을 전송하고 전환 세부정보를 기록합니다.
지오펜싱 모니터링 중지
더 이상 필요하지 않거나 원하지 않을 때 지오펜싱 모니터링을 중지하면 기기의 배터리 전력 및 CPU 주기를 절약할 수 있습니다. 지오펜싱을 추가 및 삭제하는 데 사용되는 기본 활동에서 지오펜싱 모니터링을 중지할 수 있습니다. 지오펜싱을 삭제하면 즉시 중지됩니다. API는 요청 ID를 통해 또는 주어진 PendingIntent 관련 지오펜싱을 삭제하여 지오펜싱 삭제 메서드를 제공합니다.
다음 스니펫에서는 PendingIntent 로 지오펜싱을 삭제하여 기기가 이전에 추가된 지오펜싱에 들어가거나 나올 때 발생하는 모든 추가 알림을 중지합니다.
Kotlin geofencingClient?.removeGeofences(geofencePendingIntent)?.run { addOnSuccessListener { // Geofences removed // … } addOnFailureListener { // Failed to remove geofences // … } } 자바 geofencingClient.removeGeofences(getGeofencePendingIntent()) .addOnSuccessListener(this, new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { // Geofences removed // … } }) .addOnFailureListener(this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Failed to remove geofences // … } });
지오펜싱을 정기적 위치 업데이트와 같은 다른 위치 인식 기능과 결합할 수 있습니다. 자세한 내용은 이 클래스의 다른 과정을 참조하세요.
지오펜싱 권장사항 사용
이 섹션에서는 Android용 Location API와 함께 지오펜싱을 사용하기 위한 권장사항을 간략하게 설명합니다.
전력 소비 줄이기
다음 방법을 사용하여 지오펜싱을 사용하는 앱의 전력 소비를 최적화할 수 있습니다.
알림 응답성을 더 높은 값으로 설정합니다. 이렇게 하면 지오펜싱 알림의 지연 시간이 증가하여 전력 소비가 개선됩니다. 예를 들어 응답성 값을 5분으로 설정하면 앱은 5분마다 한 번씩만 방문 또는 이탈 알림을 확인합니다. 낮은 값으로 설정한다고 해서 그 시간 내에 사용자에게 알려준다는 의미는 아닙니다. 예를 들어 값을 5초로 설정하면 알림을 받는 데는 좀 더 시간이 걸릴 수 있습니다.
집이나 직장과 같이 사용자가 많은 시간을 보내는 위치에는 더 큰 지오펜싱 반경을 사용합니다. 큰 반경으로 전력 소비가 직접적으로 줄어들지는 않지만 앱에서 방문 또는 이탈을 확인하는 빈도를 줄여 효과적으로 전체 전력 소비가 낮아집니다.
지오펜싱의 최적 반경 선택
최상의 결과를 얻으려면 지오펜싱의 최소 반경을 100~150미터로 설정해야 합니다. Wi-Fi를 사용할 수 있는 경우 위치 정확성은 일반적으로 20~50미터입니다. 실내 위치를 사용할 수 있다면 정확성 범위가 5미터까지 작아질 수 있습니다. 지오펜싱 내부에서 실내 위치의 사용 가능 여부를 알 수 없다면 Wi-Fi 위치 정확성이 약 50미터라고 가정하세요.
Wi-Fi 위치를 사용할 수 없다면(예: 시골 지역을 운전 중일 때) 위치 정확성이 떨어집니다. 정확성 범위는 수백 미터에서 수 킬로미터까지 커질 수 있습니다. 이 같은 경우 더 큰 반경을 사용하여 지오펜싱을 만들어야 합니다.
앱에서 지오펜싱을 사용하는 이유를 사용자에게 설명
지오펜싱을 사용할 때 앱이 백그라운드에서 위치에 액세스하므로 앱에서 사용자에게 혜택을 제공하는 방법을 고려하세요. 앱에 이러한 액세스 권한이 필요한 이유를 사용자에게 명확히 설명하여 사용자 이해도와 투명성을 높이세요.
지오펜싱을 포함하여 위치 정보 액세스와 관련된 권장사항에 관한 자세한 내용은 개인정보 보호 권장사항 페이지를 참고하세요.
체류 전환 유형을 사용하여 알림 스팸 줄이기
운전하며 지오펜싱을 잠시 지나갈 때 많은 알림을 받는다면 알림을 줄이는 최선의 방법은 GEOFENCE_TRANSITION_ENTER 대신 GEOFENCE_TRANSITION_DWELL 전환 유형을 사용하는 것입니다. 이렇게 하면 사용자가 주어진 시간 동안 지오펜싱 내부에서 정지할 때만 체류 알림이 전송됩니다. 배회 지연 시간을 설정하여 시간을 선택할 수 있습니다.
필요한 경우에만 지오펜싱 재등록
등록된 지오펜싱은 com.google.android.gms 패키지에서 소유한 com.google.process.location 프로세스에 보관됩니다. 앱에서는 다음 이벤트를 처리하기 위해 아무것도 할 필요가 없는데 이는 시스템에서 이러한 이벤트 후에 지오펜싱을 복원하기 때문입니다.
Google Play 서비스가 업그레이드되었습니다.
리소스 제한으로 인해 시스템에서 Google Play 서비스가 종료되었다가 다시 시작되었습니다.
위치 프로세스가 비정상 종료되었습니다.
앱에서는 다음 이벤트 후에도 여전히 필요하다면 지오펜싱을 다시 등록해야 하는데 이는 시스템에서 다음과 같은 경우에 지오펜싱을 복구할 수 없기 때문입니다.
기기가 재부팅되었습니다. 앱에서는 기기의 부팅 완료 작업을 수신 대기한 다음 필요한 지오펜싱을 다시 등록해야 합니다.
앱이 제거되었다가 다시 설치되었습니다.
앱 데이터가 삭제되었습니다.
Google Play 서비스 데이터가 삭제되었습니다.
앱에서 GEOFENCE_NOT_AVAILABLE 알림을 수신했습니다. 이는 일반적으로 NLP(Android 네트워크 위치 정보 제공자)가 사용 중지된 후에 발생합니다.
지오펜싱 방문 이벤트 문제해결
기기가 지오펜싱에 들어갈 때 지오펜싱이 트리거되지 않는다면( GEOFENCE_TRANSITION_ENTER 알림이 트리거되지 않음) 먼저 이 가이드에 설명된 대로 지오펜싱이 올바르게 등록되어 있는지 확인합니다.
예상대로 알림이 작동하지 않는 몇 가지 이유는 다음과 같습니다.
지오펜싱이란 무엇인가?
위치 기반 서비스가 최근 지오펜싱이라는 기술과 함께 많은 주목을 받고 있습니다.
지오펜스(Geofence)는 지리(Geography)와 울타리(Fence)를 결합한 단어로, 실제 위치에 기반하여 가상의 경계나 구역을 만드는 기술입니다.
지오펜스는 와이파이, 셀룰러 데이터 등의 네트워크나 비콘 등 다른 보조 기술과 결합해서 사용자의 실시간 위치와 출입 정보를 기록할 때 활용됩니다.
위치 정보를 담은 모바일 기기가 지정된 구역에 들어오면, 조건에 따라 텍스트 메시지, 이메일, 앱 알림 등 미리 정해진 특정 동작을 실행하게 됩니다.
쉽게말해 사용자의 울타리 내 출입 현황을 알려주는 것이 특징입니다.
개발자는 위도와 경도로 위치를 표시하고, 여기에 반경을 추가해 “지오펜스”가 동작하는 울타리로 둘러싸인 구역을 만듭니다.
모바일 기기에서 위치를 계산해 서버에 전달하면, 서버가 수신한 사용자 위치와 지오펜스 구역 간의 공간을 연산하고, 사용자가 지오펜스 구역에 진입할 때 근처의 정보를 다시 기기로 전달합니다.
그래서 지오펜스를 설정한 애플리케이션이나 플랫폼이 사용자나 모바일 기기가 이 구역 안에 머무는 시간, 구역 안으로 진입하는 위치, 밖으로 나가는 시점, 현재 위치를 파악할 수 있고, 조건에 따라 근방의 상점 쇼핑 정보나 쿠폰을 발송하는 등의 이벤트를 설정할 수 있습니다.
사용자도 주변 지형이나 사물과 더 깊은 실시간 상호작용을 할 수 있습니다.
지오펜싱, 누가 사용할까?
지오펜스는 주로 제조 업계에서는 공장이나 생산 현장의 제품 위치 기록과 추적에, 또 일반 기업에서는 출퇴근 기록, 보안 구역 감시 등에 지오펜스를 응용하고 있습니다.
또, 공공부문에서의 위험물 관리, 소방 등 재난 등 위기 대응 방식으로도 자리 잡았습니다.
차량 공유 서비스 리프트는 올해 초 지오펜스를 도입해 보행자와 리프트 승객을 보호할 수 있도록, 교통 혼잡도가 높고 교통법 위반 건수가 많은 지역에서 승하차를 제한하는 정책을 발표했습니다.
특히나 최근들어 핫한 분야중 하나인 드론에서도 이 기술이 적용되어 있어, 공중에서 멈추게 하거나 사용자에게 경고 메시지를 보내는 등의 행위를 할 수 있습니다.
지오펜싱에 대한 나의 생각
보안 활용성이 굉장히 중요하다고 생각하는데, 위성 정보 외에도 기업 내 무선 네트워크 기기를 이용해 사용자의 실내 위치를 정확하게 파악할 수 있기 때문에 조심해야 합니다.
이 경우 지오펜스는 특정 위치에서의 앱 액세스를 허용/제한하거나 근무 시간 조건을 설정하는 등, 보안 수준을 더 세밀하게 조정할 수 있습니다.
회의실에 들어오면 모바일 기기에 중요한 자료를 제공하고, 회의실을 나서는 순간 데이터를 삭제해 기밀을 유지하는 사례도 있습니다.
그러나 사용자들이 민감한 위치나 정보에 접근을 허용하고 알림 수신에 동의해야 마케팅 효과를 볼 수 있다는 점이 단점으로 꼽힙니다.
또, 정확한 위치를 추적할 때 배터리 소모량이 많고, 지오펜스 영역이 너무 밀집해 있을 때 맞춤형 서비스의 정확도가 떨어진다는 기술적 문제가 있습니다.
어디까지가 사용자 프라이버시이고 어디까지가 마케팅 범위인지 한계를 명확히 정해야 한다는 목소리도 높은데, 2016년에는 미국 매사추세츠 주는 최초로 위치 기반 광고 활용에 반대하는 소비자 보호법을 통과 시키기도 했습니다. 그럼에도 전문가들은 2022년까지 지오펜스 시장이 연평균 27% 성장할 것으로 내다보고 있는데 그 이유는 사람들이 무의식적으로 위치정보 서비스에 쉽게 허용을 하고 있고 공간 데이터 사용 기술이 발전하며 여러 전문 업계에서 응용분야가 늘어나기 때문이라고 생각합니다.
지오펜싱의 좋은 취지는 충분히 납득이 가지만 그 좋은 장점들이 단점으로 생각하면 끝도 없기 때문에 조금이라도 개인의 사생활을 침해받고 싶지 않다면 서비스를 이용하는데 신중하게 생각하여 개인정보를 관리하는것이 좋을 것 같습니다.