본문 바로가기

Android/Function

[안드로이드] Open API 사용하기 ― 공공 데이터 XML 파싱하기

728x90
반응형

 

 

 

안드로이드 앱개발을 하면서 공공 데이터를 사용해아할 때가 있는데요,

날씨나 교통정보등등..

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

위의 링크에 들어가면 공공데이터 api를 사용할 수 있습니다.

현재 인기검색어는 코로나네요 ^^;;

 

Api 활용 신청


 

저는 미세먼지에 대한 정보를 불러오고 싶으므로 미세먼지를 검색하여 api 신청하겠습니다.

미세먼지를 검색하고 밑으로 내려 한국환경공단_미세먼지 경보 발령 현황을 클릭해보겠습니다.

활용 신청 누르기 전에 밑의 참고 문서도 꼭 받아줍니다. 사용법이 나와있으니까요~

 

간단히 작성후 상세기능정보 선택에 꼭 쓰고싶은 부분을 체크해 주어야 합니다.

그리고 활용신청을 누르면 자동승인이 됩니다.

서비스 정보에 일반 인증키 부분을 복사하여 저장해줍니다^^

 

이제 받은 문서에 들어가 정보를 확인합니다.

http통신으로 request하여 response를 받으면 되겠네요^^

필요한 내용을 확인해 주세요.

그리고 제가 원하는 정보가 있는 페이지로 이동합니다.

pm10Value와 pm25Value를 찾아 파싱하면 되겠네요.

원하는 stationName과 서비스키에 해당하는 부분을 넣고 위의 링크를 웹에서 테스트 해보겠습니다.

서비스키에 해당하는 부분은 받은 인증키로 채워주면 됩니다. 

 

그런데..! 웹에서 서비스키를 넣고 쳐보면 SERVICE ACCESS DENIED ERROR. 를 확인할 수 있는데요.

발급하자마자 사용할 수 있는게 아니고 1시간정도 지나야 한다네요. !

안되면 2시간,3시간정도 후에 링크로 접속해보면 잘 뜨는 것을 확인할 수 있습니다.

 

XML 파싱


이제 자바코드로 원하는 데이터를 사용할 수 있도록 파싱해주겠습니다.

json으로 받으면 json 라이브러리를 사용해 파싱할 코드를 만들어야합니다. 저는 xml 파싱하였습니다.^^

먼저 http 프로토콜 허용을 위해 network_config.xml파일을 만들어 줘야 합니다.

안하면 접속 거부 나옵니다! 꼭! 추가해주세요. (안드로이드 업데이트 후에 바뀜.)

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">openapi.airkorea.or.kr</domain>
</domain-config>
</network-security-config>

위 코드를 만들어주세요.

또한 AndroidManifest.xml에 permission 추가, application에 network_config추가 합니다.

<uses-permission android:name="android.permission.INTERNET" />

...
<application
        android:name=".."
        ...
        android:networkSecurityConfig="@xml/network_config">
        ...
</application>
...

 

이제 Network 접속이므로 Thread나 AsyncTask를 이용하면 됩니다. (AsyncTask사용)

public class OpenAPI extends AsyncTask<Void, Void, String> {

        private String url;

        public OpenAPI(String url) {

            this.url = url;
        }

        @Override
        protected String doInBackground(Void... params) {

            // parsing할 url 지정(API 키 포함해서)

            DocumentBuilderFactory dbFactoty = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = null;
            try {
                dBuilder = dbFactoty.newDocumentBuilder();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            }
            Document doc = null;
            try {
                doc = dBuilder.parse(url);
            } catch (IOException | SAXException e) {
                e.printStackTrace();
            }

            // root tag
            doc.getDocumentElement().normalize();
            System.out.println("Root element: " + doc.getDocumentElement().getNodeName()); // Root element: result

            // 파싱할 tag
            NodeList nList = doc.getElementsByTagName("item");
           
            for(int temp = 0; temp < nList.getLength(); temp++){
                Node nNode = nList.item(temp);
                if(nNode.getNodeType() == Node.ELEMENT_NODE){

                    Element eElement = (Element) nNode;
                    Log.d("OPEN_API","data Time  : " + getTagValue("dataTime", eElement));
                    Log.d("OPEN_API","미세먼지  : " + getTagValue("pm10Value", eElement));
                    Log.d("OPEN_API","초미세먼지 : " + getTagValue("pm25Value", eElement));
                }	// for end
            }	// if end
            return null;
        }

        @Override
        protected void onPostExecute(String str) {
            super.onPostExecute(str);
        }
}

private String getTagValue(String tag, Element eElement) {
     NodeList nlList = eElement.getElementsByTagName(tag).item(0).getChildNodes();
     Node nValue = (Node) nlList.item(0);
     if(nValue == null)
       return null;
     return nValue.getNodeValue();
}

doInBackground에 다 코드를 넣어놨습니다. 

중간에 파싱할 tag도 자신이 활용할 tag에 맞게 바꾸어주어야합니다.

String url = "data_url";
OpenAPI dust = new OpenAPI(url);
dust.execute();

이제 위처럼 활용할 data url을 넣어주기만 하여 사용할 수 있습니다.

 

 

잘 출력되는것을 확인할 수 있죠!


 

 

728x90
반응형