Notice
Recent Posts
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags more
관리 메뉴

MyWorld

[Android : Java] Naver Map 도로명주소 찾는 기능 사용 본문

Android 앱 개발 (Java)

[Android : Java] Naver Map 도로명주소 찾는 기능 사용

vBest 2021. 6. 3. 14:02

도로명주소를 찾아 맨 위에 검색된 값과 그 우편번호를 가져오는 코드를 작성해봤다.

 

1. Naver Cloud Platform에 회원 가입하고 카드를 등록한다.

(카드 등록을 해도 돈이 나가지 않는다. 등록해야만 API를 사용할 수 있다)

 

마이페이지> 결제수단 관리에서 카드 등록하면 된다. (체크카드도 가능했다)

2. Console로 들어가서 Producy&Services에서 AI·NAVER API를 찾아 ★을 눌러 북마크 한다.

북마크에 AI·NAVER API가 뜰 것이다. 누르면 어플리케이션을 추가할 수 있다. 나는 Map API 중에서도 사용이 무료인 것만 사용했다. 선택 가능한 것들 중 유료도 있으니 주의해서 진행하길 바란다. 

어플리케이션 등록을 누르면 나오는 화면이다. 앱 패키지 이름 등록이 필요하다.

3. Client ID / Client secret를 복사해둔다.

4. 이제 개발 가이드 바로가기를 눌러 API 사용법을 알아보자.

Maps의 Geocoding으로 들어간다. 

나는 도로명 주소 반환을 원하기 때문에 Geocoding API v2를 열었다. 

대략적인 Geocoding 사용방법을 볼 수 있다.

프로젝트에서 어떻게 사용할 수 있을지 알아보자.

5. 프로젝트에서 API 활용을 위해 Build.Gradle(:app)에 다음을 추가한다.

레트로핏은 서버와 HTTP 통신을 하고 서버로부터 받은 데이터를 사용자가 볼 수 있게 앱에서 출력하는 라이브러리다.

    // retrofit
    def retrofit_version = "2.9.0"
    implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
    implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version"

    // okHttp
    def ok_http_version = "4.5.0"
    implementation "com.squareup.okhttp3:okhttp:$ok_http_version"
    implementation "com.squareup.okhttp3:logging-interceptor:$ok_http_version"

    //gson
    implementation 'com.google.code.gson:gson:2.8.6'

6. 프로젝트에 NaverMapApi 인터페이스를 만들어준다

3번에서 받은 클라이언트 아이디클라이언트 시크릿 값을 넣어준다.

package data.remote;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.Query;

public interface NaverMapApi {
    /**   https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode
     ?query=분당구 불정로 6
     &X-NCP-APIGW-API-KEY-ID=클라이언트 아이디
     &X-NCP-APIGW-API-KEY=클라이언트 시크릿
     **/

    /**
     * curl -G "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode" \
     --data-urlencode "query=분당구 불정로 6" \
     --data-urlencode "coordinate=127.1054328,37.3595963" \
     -H "X-NCP-APIGW-API-KEY-ID: {애플리케이션 등록 시 발급받은 client id값}" \
     -H "X-NCP-APIGW-API-KEY: {애플리케이션 등록 시 발급받은 client secret값}" -v

     */

    @Headers(
            {
                    "X-NCP-APIGW-API-KEY-ID: 클라이언트 아이디 ",
                    "X-NCP-APIGW-API-KEY: 클라이언트 시크릿 "
            }
    )
    @GET("/map-geocode/v2/geocode")
    public Call<AddressResponse> searchAddress(@Query("query") String query );

}

주석 처리한 https://..... 부분을 크롬에 검색하면 (크롬에 JSON Viewer를 설치해둬야 한다) 

다음과 같은 형태로 응답을 받아온다.

// 20210603124109
// https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query= .... (검색한 링크)
{
  "status": "OK",
  "meta": {
    "totalCount": 1,
    "page": 1,
    "count": 1
  },
  "addresses": [
    {
      "roadAddress": "경기도 성남시 분당구 불정로 6 그린팩토리",
      "jibunAddress": "경기도 성남시 분당구 정자동 178-1 그린팩토리",
      "englishAddress": "6, Buljeong-ro, Bundang-gu, Seongnam-si, Gyeonggi-do, Republic of Korea",
      "addressElements": [
        {
          "types": [
            "SIDO"
          ],
          "longName": "경기도",
          "shortName": "경기도",
          "code": ""
        },
        {
          "types": [
            "SIGUGUN"
          ],
          "longName": "성남시 분당구",
          "shortName": "성남시 분당구",
          "code": ""
        },
        {
          "types": [
            "DONGMYUN"
          ],
          "longName": "정자동",
          "shortName": "정자동",
          "code": ""
        },
        {
          "types": [
            "RI"
          ],
          "longName": "",
          "shortName": "",
          "code": ""
        },
        {
          "types": [
            "ROAD_NAME"
          ],
          "longName": "불정로",
          "shortName": "불정로",
          "code": ""
        },
        {
          "types": [
            "BUILDING_NUMBER"
          ],
          "longName": "6",
          "shortName": "6",
          "code": ""
        },
        {
          "types": [
            "BUILDING_NAME"
          ],
          "longName": "그린팩토리",
          "shortName": "그린팩토리",
          "code": ""
        },
        {
          "types": [
            "LAND_NUMBER"
          ],
          "longName": "178-1",
          "shortName": "178-1",
          "code": ""
        },
        {
          "types": [
            "POSTAL_CODE"
          ],
          "longName": "13561",
          "shortName": "13561",
          "code": ""
        }
      ],
      "x": "127.1054065",
      "y": "37.3595669",
      "distance": 0.0
    }
  ],
  "errorMessage": ""
}

7.  AddressResponse.java를 만들어준다.

 위 응답 내용 중 도로명주소우편번호를 받아오기 위해 다음과 같은 코드를 작성했다.

package data.remote;

import androidx.annotation.Keep;

import java.util.Arrays;

@Keep
public class AddressResponse {
    AddressData[] addresses;

    @Keep
    private class AddressData {
        String roadAddress;
        AdressElement[] addressElements;

        @Keep
        private class AdressElement {
            String[] types;
            String longName;

            @Override
            public String toString() {
                return "AdressElement{" +
                        "types=" + Arrays.toString(types) +
                        ", longName='" + longName + '\'' +
                        '}';
            }
        }

        @Override
        public String toString() {
            return "AddressData{" +
                    "loadAddress='" + roadAddress + '\'' +
                    ", addressElements=" + Arrays.toString(addressElements) +
                    '}';
        }
    }

    @Override
    public String toString() {
        String postalCode="";
        for (AddressData.AdressElement element : addresses[0].addressElements){
            for (String type : element.types){
                if (type.equals("POSTAL_CODE")){
                    postalCode = element.longName;
                    break;
                }
            }
            if (!postalCode.equals("")){
                break;
            }
        }

        return addresses[0].roadAddress+"\n"+postalCode;
    }
}

도로명 주소 검색을 할 준비가 마쳤다. 

8. 도로명주소 찾는 코드 

searchAddress는 도로명 주소를 찾는 메소드다.

주소 textview와  우편번호 textview에 서버의 응답을 레트로핏으로 받아와 사용한다.

    private void searchAddress(String query,final TextView postcode, final TextView home1) {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.MINUTES)
                .readTimeout(10,TimeUnit.SECONDS)
                .writeTimeout(10,TimeUnit.SECONDS)
                .build();
        Gson gson = new GsonBuilder().setLenient().create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://naveropenapi.apigw.ntruss.com/")
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();

        retrofit.create(data.remote.NaverMapApi.class).searchAddress(query).enqueue(new Callback<AddressResponse>() {
            @Override
            public void onResponse(Call<AddressResponse> call, Response<AddressResponse> response) {
                String post = response.body().toString();
                String address = post.split("\n")[0];
                String postCode = post.split("\n")[1];
                Log.e("res",response.body().toString());
                home1.setText(address); //주소 텍스트뷰에 도로명주소
                postcode.setText(postCode); //우편번호 텍스트뷰에 우편번호  
            }

            @Override
            public void onFailure(Call<AddressResponse> call, Throwable t) {

            }
        });
    }
//다이얼로그에서 "주소 변환" 확인 버튼 누르면 동작
        okButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // '확인' 버튼 클릭시 메인 액티비티에서 설정한 postcode ,home1 에
                searchAddress(inputAddress.getText().toString(),postcode,home1); //
                // 커스텀 다이얼로그를 종료한다.
                dlg.dismiss();
            }
        });

나는 위와 같이 주소변환 버튼을 누르면 다이얼로그가 뜨고

주소 정보 입력 후 다이얼로그의 확인 버튼을 누르면  searchAddress 메소드를 호출하도록 만들었다.

 

다음은 프로젝트에 적용한 결과 화면이다.