Android에서 GPS 위치 정보를 사용하는 방법
지도 표시, 주행 기록, 주변 정보 검색처럼 위치가 필요한 기능은 생각보다 고려할 것이 많습니다.
단순히 GPS를 켜고 좌표를 받는 작업이 아니라, 권한·배터리·정확도·통신 상태까지 함께
다뤄야 안정적인 기능이 됩니다. 이번 글에서는 Android 기본 위치 API인
LocationManager를 기준으로 정리해 보겠습니다.
목차
- GPS 기능을 만들기 전 고려할 점
- 위치 Provider란?
- GPS Provider와 Network Provider의 차이
- Android 버전별 위치 권한
- 위치 정보 수신 샘플 코드
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()를 호출해 불필요한 위치 수신을 멈추는 것이 좋습니다.
위치 기능의 핵심은 “가장 정확한 위치”보다 “기능에 필요한 만큼만, 사용자에게 투명하게”
사용하는 데 있습니다.

댓글
댓글 쓰기