본문 바로가기
안드로이드 자바

[Android][Java] 현재 위치의 위경도 Geocoder로 주소 변환하기

by teamnova 2023. 8. 17.

안녕하세요 이번 포스팅에서는 현재 위치의 위경도를 받아오고 Geocoder를 이용해 주소로 변환하는 예제를 작성하겠습니다. 

 

우선 저는 네이버 지도 api를 사용했고 해당 api 사용법은 아래 포스팅에서 확인할 수 있습니다.

https://stickode.tistory.com/767

 

[Android][Java] 네이버 맵 API 사용하기

이번 포스팅에서는 안드로이드 스튜디오에서 네이버 지도 API 를 이용해 네이버 지도를 띄워보겠습니다. 1. Client ID 발급하기 (1) 네이버 클라우드 플랫폼에서 로그인 한 다음 콘솔에 들어갑니다.

stickode.tistory.com

우선 현재 위치의 위경도를 받아오는 방법에 대해 작성하겠습니다.

참고할 수 있는 포스팅은 다음과 같습니다.

https://stickode.tistory.com/778

 

[Android][Java] 네이버 지도에 현재 위치 표시하기

네이버 지도 API 를 이용해 지도를 띄우는 것을 완료했다면 이젠 유저의 현재 위치를 표시해보겠습니다. 네이버 지도 api 개발자 가이드에 위치를 표시하는 방법에 대해 설명되어 있으니 참고바

stickode.tistory.com

우선 Geocoder에 대해서 설명하겠습니다.

아래 링크는 안드로이드 공식 홈페이지에서 설명하는 Geocoder입니다.

공부할때 참고하시면 좋을것같아 첨부합니다.

https://developer.android.com/reference/android/location/Geocoder

 

Geocoder  |  Android Developers

 

developer.android.com

Geocoder는 안드로이드에서 제공하는 클래스 중 하나로, 위도와 경도를 주소 또는 주소를 위도, 경도로 변환하는 등의 지리적인 정보를 변환하는 기능을 제공ㅎ바니다.

정리하자면 지오코딩(Geocoding) & 역지오코딩(Reverse geocodint) 기능을 제공하는데 지오코딩은 주소나 장소명으로 위도, 경도를 얻는 것이고, 역지오코딩은 위도,경도로 주소나 장소명을 얻는 것입니다.

 

하지만 Geocoder 클래스는 안드로이드 프레임워크에서 제공하는 백엔드 서비스를 필요로 합니다. 백엔드서비스가 없는 플랫폼에서는 Geocoder 쿼리 메서드가 빈 목록을 반환합니다. Geocoder 구현체가 있는지 확인하려면 isPresent()메서드를 사용해야합니다. 또한 Geocoder 클래스는 안드로이드 내장 데이터를 사용하므로 데이터의 정확성과 갱신 속도 등에 제한이 있을 수 있습니다. 이러한 이유로 Geocoder를 사용하기 전에 해당 디바이스에서 Geocoder가 지원되는지 확인하고 데이터의 정확성에 대한 검토가 필요합니다.

 

전체 코드 입니다.

package com.example.everyrunrenew;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentManager;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

import com.naver.maps.geometry.LatLng;
import com.naver.maps.map.LocationTrackingMode;
import com.naver.maps.map.MapFragment;
import com.naver.maps.map.NaverMap;
import com.naver.maps.map.OnMapReadyCallback;
import com.naver.maps.map.overlay.InfoWindow;
import com.naver.maps.map.util.FusedLocationSource;

import java.io.IOException;
import java.util.List;

public class Stick_map_Activity extends AppCompatActivity implements OnMapReadyCallback {
    private final String TAG = this.getClass().getSimpleName(); // log 태그
    private FusedLocationSource locationSource; // 위치 정보 소스
    private NaverMap mNaverMap; // NaverMap 객체

    LocationManager locationManager; // 위치 관리자

    // 필요한 권한들
    private static final int PERMISSION_REQUEST_CODE = 100;
    private static final String[] PERMISSIONS = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    };

    double longitude; // 위도
    double latitude; // 경도
    List<Address> addressList = null; // 받아올 주소 리스트
    String address;
    // GPS 프로바이더 사용 가능 여부, 네트워크 프로바이더 사용 가능 여부, 프로파이더
    boolean isGPSEnabled;
    boolean isNetworkEnabled;
    String provider;

    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stick_map);
        context = getApplicationContext();
        //지도 객체 생성하기
        FragmentManager fragmentManager = getSupportFragmentManager();
        MapFragment mapFragment = (MapFragment) fragmentManager.findFragmentById(R.id.map);

        // 맵프래그먼트가 null이면 새로 생성
        if(mapFragment == null){
            mapFragment = MapFragment.newInstance();
            fragmentManager.beginTransaction().add(R.id.stick_map, mapFragment).commit();

        }

        //getMapAsync 호출해 비동기로 onMapReady 콜백 메서드 호출
        //onMapReady에서 NaverMap 객체를 받음.
        mapFragment.getMapAsync(this);

        //위치를 반환하는 구현체인 FusedLocationSource 생성
        locationSource = new FusedLocationSource(this, PERMISSION_REQUEST_CODE);


    }

    @Override
    public void onMapReady(@NonNull NaverMap naverMap) {

        // NaverMap 객체 받아서 NaverMap 객체에 위치 소스 지정
        mNaverMap = naverMap;
        mNaverMap.setLocationSource(locationSource);
        mNaverMap.setMaxZoom(18.0); // 지도 줌

        // 유저의 현재 위치 가져오기
        GetUserLocation();

        // 정보창 생성 - 현재 주소 표시
        InfoWindow infoWindow = new InfoWindow();
        infoWindow.setAdapter(new InfoWindow.DefaultTextAdapter(context) {
            @NonNull
            @Override
            public CharSequence getText(@NonNull InfoWindow infoWindow) {
                return address;
            }
        });

        // 위경도
        LatLng latLng = new LatLng(latitude,longitude);
        infoWindow.setPosition(latLng); // 현재 위경도에 해당하는 위치에 정보창 세팅하기
        infoWindow.open(mNaverMap);

        // 권한 확인, 결과는 onRequestPermissionResult 콜백 메서드 호출
        ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_REQUEST_CODE);

    }

    // 유저 현재 위치 받아오는 메서드
    @SuppressLint("MissingPermission")
    private void GetUserLocation() {

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

        // GPS 프로바이더 사용가능여부
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        // 네트워크 프로바이더 사용가능여부
        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        Log.d("Main", "isGPSEnabled="+ isGPSEnabled);
        Log.d("Main", "isNetworkEnabled="+ isNetworkEnabled);

        LocationListener locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(@NonNull Location location) {
                // 현재 위치의 위도 경도 받아오기
                latitude = location.getLatitude();
                longitude = location.getLongitude();

                Log.d(TAG, "onLocationChanged: latitude =" + latitude);
                Log.d(TAG, "onLocationChanged: longitude =" + longitude);

            }
        };
        // 위치 업데이트 요청
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,0, locationListener);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0,locationListener);
        // 마지막으로 알려진 위치 가져오기
        provider = LocationManager.GPS_PROVIDER;
        Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
        if(lastKnownLocation != null) {
            latitude = lastKnownLocation.getLatitude();
            longitude = lastKnownLocation.getLongitude();
            Log.d(TAG, "GetUserLoction: lastKnownLocation != null");
            Log.d(TAG, "GetUserLoction: latitude =" + latitude);
            Log.d(TAG, "GetUserLoction: longitude =" + longitude);
            // 위도 경도로 주소 변환하기.
            Geocoder g = new Geocoder(Stick_map_Activity.this);

            // 위도 경도로 주소 변환하기
            try{
                addressList = g.getFromLocation(latitude, longitude, 10);

            } catch (IOException e) {
                e.printStackTrace();
                Log.d(TAG, "GetUserLoction: 입출력 오류");
            }

            if(addressList != null){
                if(addressList.size() == 0){
                    Log.d(TAG, "GetUserLoction: 주소 찾기 오류");
                }else{
                    Log.d(TAG, "GetUserLoction: 찾은 주소 =" + addressList.get(0).toString());
                    Log.d(TAG, "GetUserLoction: 주소 =" + addressList.get(0).getAddressLine(0));
                    address = addressList.get(0).getAddressLine(0);
                }
            }
        }

    }

    // 권한 요청 결과 처리하는 메서드
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // request code와 권한 획득 여부 확인
        if(requestCode == PERMISSION_REQUEST_CODE){
            if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                mNaverMap.setLocationTrackingMode(LocationTrackingMode.Follow);
            }
        }
    }




}

다음은 시연 영상입니다.