기본 콘텐츠로 건너뛰기

Android에서 GPS 위치 정보를 사용하는 방법

Android에서 GPS 위치 정보를 사용하는 방법




지도 표시, 주행 기록, 주변 정보 검색처럼 위치가 필요한 기능은 생각보다 고려할 것이 많습니다. 단순히 GPS를 켜고 좌표를 받는 작업이 아니라, 권한·배터리·정확도·통신 상태까지 함께 다뤄야 안정적인 기능이 됩니다. 이번 글에서는 Android 기본 위치 API인 LocationManager를 기준으로 정리해 보겠습니다.

목차

  1. GPS 기능을 만들기 전 고려할 점
  2. 위치 Provider란?
  3. GPS Provider와 Network Provider의 차이
  4. Android 버전별 위치 권한
  5. 위치 정보 수신 샘플 코드

1. GPS 기능을 만들기 전 고려할 점

위치 정보는 민감한 개인정보입니다. 따라서 “정말 정확한 위치가 필요한가?”부터 먼저 판단하는 것이 좋습니다. 단순히 사용자의 현재 도시나 주변 매장 정도만 알면 되는 기능이라면 대략적인 위치 권한으로도 충분할 수 있습니다.

  • 현재 위치가 꼭 필요한 시점에만 권한을 요청합니다.
  • 정확한 위치가 필요 없다면 대략적 위치 권한을 우선 고려합니다.
  • 위치 업데이트 주기가 짧을수록 배터리 사용량이 커집니다.
  • GPS는 실내, 지하 주차장, 터널 등에서 수신이 늦거나 불가능할 수 있습니다.
  • 사용자가 권한을 거부하거나 위치 서비스를 꺼 둔 경우도 처리해야 합니다.

2. 위치 Provider란?

Provider는 Android가 “어떤 방법으로 위치를 계산할지” 선택하는 기준입니다. LocationManager는 대표적으로 GPS와 네트워크 Provider를 제공합니다. 앱은 필요한 정확도와 배터리 사용량을 고려해 Provider를 선택할 수 있습니다.

Provider 위치 계산 방식 특징
GPS_PROVIDER GNSS 위성 신호 정확도가 높지만 실내에 약하고, 첫 위치 수신까지 시간이 걸릴 수 있습니다.
NETWORK_PROVIDER Wi-Fi AP, 기지국 등 네트워크 정보 위치를 비교적 빠르게 얻을 수 있고 실내에서도 유리하지만, 정확도는 환경에 따라 달라집니다.
PASSIVE_PROVIDER 다른 앱·서비스가 이미 수신한 위치 직접 위치를 요청하지 않아 배터리 부담이 적지만, 새 위치를 보장하지는 않습니다.

3. GPS Provider와 Network Provider의 차이

주행 기록이나 내비게이션처럼 정확한 좌표가 중요한 기능은 GPS_PROVIDER가 적합합니다. 반대로 앱을 열었을 때 빠르게 대략적인 위치를 보여주고 싶다면 NETWORK_PROVIDER가 더 좋은 선택일 수 있습니다.

실제 서비스에서는 둘 중 하나만 고집하기보다, 먼저 네트워크 위치로 빠르게 시작하고 GPS 위치가 들어오면 더 정확한 값으로 갱신하는 방식도 많이 사용합니다. 단, 각 Provider가 항상 사용 가능한 것은 아니므로 isProviderEnabled()로 상태를 확인해야 합니다.

4. Android 버전별 위치 권한

  • Android 6.0(API 23) 이상: Manifest 선언만으로는 부족하며, 실행 중에도 사용자에게 위치 권한을 요청해야 합니다.
  • Android 10(API 29) 이상: 앱이 화면에 없을 때도 위치를 계속 사용해야 한다면 ACCESS_BACKGROUND_LOCATION 권한이 추가로 필요합니다.
  • Android 12(API 31) 이상: 사용자는 정확한 위치 대신 대략적인 위치를 선택할 수 있습니다. 정확한 위치가 필요하다면 ACCESS_FINE_LOCATION과 ACCESS_COARSE_LOCATION을 함께 요청해야 합니다.

백그라운드 위치 권한은 정말 핵심 기능일 때만 요청하는 것이 좋습니다. 예를 들어 화면을 닫아도 계속되는 주행 기록이나 지오펜싱 기능이 이에 해당합니다. 일반적인 화면 내 위치 조회는 포그라운드 위치 권한만으로 충분합니다.

AndroidManifest.xml 권한 선언

<!-- 대략적인 위치 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- 정확한 위치 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- 화면 밖에서도 위치가 꼭 필요할 때만 선언 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

5. 위치 정보 수신 샘플 코드

아래 코드는 위치 권한을 확인한 뒤, GPS가 켜져 있으면 GPS Provider를 사용하고 그렇지 않으면 Network Provider를 사용하는 간단한 예제입니다.

public class MainActivity extends AppCompatActivity {

    private static final int LOCATION_PERMISSION_REQUEST = 100;
    private LocationManager locationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        locationManager =
                (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        requestLocationPermission();
    }

    private void requestLocationPermission() {
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED) {
            startLocationUpdates();
            return;
        }

        ActivityCompat.requestPermissions(
                this,
                new String[] {
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION
                },
                LOCATION_PERMISSION_REQUEST
        );
    }

    private void startLocationUpdates() {
        String provider;

        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            provider = LocationManager.GPS_PROVIDER;
        } else if (locationManager.isProviderEnabled(
                LocationManager.NETWORK_PROVIDER)) {
            provider = LocationManager.NETWORK_PROVIDER;
        } else {
            Toast.makeText(this, "위치 서비스를 켜 주세요.", Toast.LENGTH_SHORT).show();
            return;
        }

        LocationListener listener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();

                Log.d("LOCATION", "위도: " + latitude);
                Log.d("LOCATION", "경도: " + longitude);
            }
        };

        locationManager.requestLocationUpdates(
                provider,
                3000L,  // 최소 3초 간격
                10f,    // 최소 10m 이동 시
                listener
        );
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode,
            @NonNull String[] permissions,
            @NonNull int[] grantResults
    ) {
        super.onRequestPermissionsResult(
                requestCode,
                permissions,
                grantResults
        );

        if (requestCode == LOCATION_PERMISSION_REQUEST
                && grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startLocationUpdates();
        }
    }
}

예제에서는 3초 또는 10m 이동을 기준으로 위치를 갱신합니다. 실제 앱에서는 화면을 벗어날 때 removeUpdates()를 호출해 불필요한 위치 수신을 멈추는 것이 좋습니다. 위치 기능의 핵심은 “가장 정확한 위치”보다 “기능에 필요한 만큼만, 사용자에게 투명하게” 사용하는 데 있습니다.


참고: Android 위치 권한 공식 문서 , LocationManager API 문서

댓글

이 블로그의 인기 게시물

Android에서 Bluetooth 통신을 사용하는 방법

Android에서 Bluetooth 통신을 사용하는 방법 Bluetooth는 스마트폰과 차량용 기기, 센서, 블랙박스, 이어폰처럼 가까운 장치끼리 무선으로 데이터를 주고받을 때 사용하는 기능입니다. Android에서는 기기 검색부터 연결, 데이터 송수신까지 API로 처리할 수 있습니다. 이번 글에서는 Bluetooth 통신을 시작할 때 알아두면 좋은 개념과 권한, 그리고 간단한 연결 예제를 정리해 보겠습니다. 목차 Bluetooth 통신을 만들기 전 고려할 점 Bluetooth Classic과 BLE의 차이 Android 버전별 Bluetooth 권한 Bluetooth 통신 흐름 연결 및 데이터 전송 샘플 코드 1. Bluetooth 통신을 만들기 전 고려할 점 Bluetooth는 가까운 거리에서 편리하게 통신할 수 있지만, 항상 연결되어 있다고 가정하면 안 됩니다. 기기 전원이 꺼지거나 통신 범위를 벗어나면 연결이 끊길 수 있고, 페어링 여부나 장치별 지원 프로파일도 다를 수 있습니다. 기기에 Bluetooth 기능이 있는지 확인합니다. 사용자가 Bluetooth를 꺼 둔 경우, 켜도록 안내합니다. 연결·데이터 수신 작업은 메인 스레드가 아닌 별도 스레드에서 처리합니다. 연결 실패와 연결 해제 상황을 항상 처리합니다. 기기마다 통신 규격과 UUID, 데이터 형식이 다를 수 있음을 고려합니다. 2. Bluetooth Classic과 BLE의 차이 Bluetooth는 크게 Bluetooth Classic 과 Bluetooth Low Energy(BLE) 로 나눌 수 있습니다. 이름은 비슷하지만 통신 방식과 잘 맞는 사용 사례가 다릅니다. 구분 Bluetooth Classic BLE 특징 지속적인 데이터 전송에 적합 낮...

Android에서 BLE 통신을 사용하는 방법

Android에서 BLE 통신을 사용하는 방법 BLE(Bluetooth Low Energy)는 이름 그대로 전력 사용량을 낮춘 Bluetooth 통신 방식입니다. 센서, 비콘, 건강 측정기, 소형 IoT 기기처럼 작은 데이터를 주기적으로 주고받는 환경에 특히 잘 맞습니다. Classic Bluetooth와 달리 소켓으로 자유롭게 데이터를 주고받기보다, 정해진 GATT 구조 안에서 데이터를 읽고 쓰는 방식으로 동작합니다. 목차 BLE를 사용하기 전 알아둘 점 BLE의 핵심 구조: Central, Peripheral, GATT Service와 Characteristic 이해하기 Android 버전별 BLE 권한 BLE 통신 흐름 스캔 및 연결 샘플 코드 1. BLE를 사용하기 전 알아둘 점 BLE는 배터리 효율이 좋지만, 많은 양의 데이터를 빠르게 전송하는 용도에는 적합하지 않을 수 있습니다. 연결하려는 기기가 제공하는 Service UUID와 Characteristic UUID, 데이터 형식은 제조사 문서나 기기 사양으로 반드시 확인해야 합니다. BLE는 작은 데이터를 주기적으로 전송하는 데 적합합니다. 스캔은 배터리 사용량이 크므로 시간 제한을 두고, 기기를 찾으면 바로 멈춥니다. 기기별 UUID와 데이터 형식은 다르므로 공통값으로 가정하면 안 됩니다. 연결, 서비스 탐색, 데이터 수신은 모두 비동기 콜백으로 처리됩니다. 연결이 끝나면 disconnect() 와 close() 로 리소스를 해제합니다. 2. BLE의 핵심 구조: Central, Peripheral, GATT BLE에서는 스마트폰이 보통 Central 역할을 맡습니다. 주변 BLE 기기를 스캔하고 연결을 요청하는 쪽입니다. 센서나 측정 장치는 Peripheral 역할을 하며, 자신의 데이터와 기능을 외부에 제공합니다. 이때 데이터의 구조와 접근 방식은 G...

안드로이드 기초 파트 1: 안드로이드 개발 환경 설정

파트 1: 안드로이드 개발 환경 설정 1.1 안드로이드 스튜디오 설치 및 설정 1.2 안드로이드 SDK 및 필수 도구 설치 1.3 에뮬레이터 또는 실제 기기 연결 1.4 첫 번째 프로젝트 생성 및 "Hello, World!" 출력 1.5 안드로이드 스튜디오 기본 사용법 (프로젝트 구조, 주요 기능 소개)