Develop/Kotlin

[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(JSON 문서)

JunJangE 2021. 8. 8. 13:26

이전에 XML 형식으로 오픈 API를 요청하여 데이터를 확인해 보았다.

 

[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(XML)

이번에는 다양한 데이터가 있는 공공데이터 포털을 통해 오픈 API를 활용해려고한다. 공공데이터 포털 국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법

fre2-dom.tistory.com

이번에는 JSON 형식으로 오픈 API를 요청하여 데이터를 확인해보자.

공공데이터 오픈 API를 신청하는 방법은 위 링크를 통해 알아보고 오면 좋을 것 같다.

그럼 공공데이터 오픈 API 신청까지 끝났다고 가정하고 진행하겠다.

우선 기본 정보 목록 조회 미리 보기 과정에서 JSON으로 요청하기 위해 “&_type=json”을 추가하여 요청한다.

JSON 문서

그럼 위 사진처럼 나오게 되는데 너무 복잡하게 나와있으므로 JSON 문서를 다음 사이트에서 복붙 하여 JSON 문서 배열을 보기 쉽게 확인한다.

 

The JSON Validator

JSONLint is the free online validator and reformatter tool for JSON, a lightweight data-interchange format.

jsonlint.com

JSON 문서

복사 붙여 넣기 하고 Validate JSON을 누르면 JSON 문서 배열을 보기 쉽게 확인할 수 있다.

여기서 우리가 가져올 데이터는 다음과 같다.

addr1 = 주소

facltNm = 캠핑장 이름

induty = 업종

tel = 전화번호

mapX = 위도

mapY = 경도

우리는 위 정보만을 가져오는 코드를 작성하자.

주석을 잘 확인하면서 코드를 작성하면 좋을 것 같다.

network_security_config

먼저 네트워크 보안 구성을 위해 res 파일에 xml 리소스 파일을 만든다.

파일 이름은 network_security_config 선언했다.

생성된 파일에는 다음 코드를 작성한다.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!--Set application-wide security config using base-config tag.-->
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

MainActivity

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.URL


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 택스트 뷰 생성
        textView.text = ""

        // 버튼을 누르면 쓰레드 동작
        button.setOnClickListener {

            // 쓰레드 생성
            val thread = NetworkThread()
            thread.start()
            thread.join()
        }
    }

    // 네트워크를 이용할 때는 쓰레드를 사용해서 접근해야 함
    inner class NetworkThread: Thread(){
        override fun run() {

            // 키 값
            val key = "키값"

            // 현재 페이지번호
            val pageNo = "&pageNo=1"

            // 한 페이지 결과 수
            val numOfRows ="&numOfRows=10"

            // AND(안드로이드)
            val MobileOS = "&MobileOS=AND"

            // 서비스명 = 어플명
            val MobileApp = "&MobileApp=AppTest"

            // API 정보를 가지고 있는 주소
            val site = "http://api.visitkorea.or.kr/openapi/service/rest/GoCamping/basedList?serviceKey="+key+pageNo+numOfRows+MobileOS+MobileApp+"&_type=json"

            val url = URL(site)
            val conn = url.openConnection()
            val input = conn.getInputStream()
            val isr = InputStreamReader(input)
            // br: 라인 단위로 데이터를 읽어오기 위해서 만듦
            val br = BufferedReader(isr)

            // Json 문서는 일단 문자열로 데이터를 모두 읽어온 후, Json에 관련된 객체를 만들어서 데이터를 가져옴
            var str: String? = null
            val buf = StringBuffer()

            do{
                str = br.readLine()

                if(str!=null){
                    buf.append(str)
                }
            }while (str!=null)

            // 전체가 객체로 묶여있기 때문에 객체형태로 가져옴
            val root = JSONObject(buf.toString())
            val response = root.getJSONObject("response").getJSONObject("body").getJSONObject("items")
            val item = response.getJSONArray("item") // 객체 안에 있는 item이라는 이름의 리스트를 가져옴

            // 화면에 출력
            runOnUiThread {

                // 페이지 수만큼 반복하여 데이터를 불러온다.
                for(i in 0 until item.length()){

                    // 쪽수 별로 데이터를 읽는다.
                    val jObject = item.getJSONObject(i)

                    textView.append("${i + 1}번 캠핑장 \n")
                    textView.append("1. 주소: ${ JSON_Parse(jObject,"addr1")}\n")
                    textView.append("2. 캠핑장 이름: ${JSON_Parse(jObject,"facltNm")}\n")
                    textView.append("3. 업종: ${JSON_Parse(jObject,"induty")}\n")
                    textView.append("4. 전화번호: ${ JSON_Parse(jObject,"tel")}\n")
                    textView.append("5. 경도: ${JSON_Parse(jObject,"mapX")}\n")
                    textView.append("6. 위도: ${JSON_Parse(jObject,"mapY")}\n")
                }
            }
        }

        // 함수를 통해 데이터를 불러온다.
        fun JSON_Parse(obj:JSONObject, data : String): String {

            // 원하는 정보를 불러와 리턴받고 없는 정보는 캐치하여 "없습니다."로 리턴받는다.
            return try {

                obj.getString(data)

            } catch (e: Exception) {
                "없습니다."
            }
        }
    }

}

activitiy.main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button" />


        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="1500dp"
            android:text="TextView" />

    </LinearLayout>

</ScrollView>

AndroidMainfest.xml

 <!--인터넷 권한 허용 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    
    <!-- <application
       android:networkSecurityConfig="@xml/network_security_config"
         
       android:usesCleartextTraffic="true" 인터넷 웹뷰로 불러올때 s를 만들어준다?
       앱이 일반 텍스트 HTTP와 같은 일반 텍스트 네트워크 트래픽을 사용하는지 여부를 나타낸다.
       
       
       </application>  -->

위 코드를 모두 작성하고 실행하면 다음 결과 화면과 같이 나오는 것을 확인할 수 있다.

결과 화면

참고

 

오픈 API 데이터 가져오기(JSON 문서)

- 공공 데이터 포털에서 오픈 API인 주소 기준 동네별 공적 마스크 판매정보 제공 서비스(https://www.data.go.kr/data/15057411/openapi.do)를 이용해서 데이터를 가져오는 연습을 할 것 - URL을 누르면 아래와..

hyeals.tistory.com

 

 

[Android] 네트워크 보안구성 문제

문제점 안드로이드Pi (9.0) 버젼에서 http통신을 이용한 app을 만들어보려 하는 와중에 오류가 발생하기 시작했다. error : No Network Security Config specified, using platform default...

kimboomin.blogspot.com

github

 

GitHub - junjange/Kotlin-Learning: 코틀린 학습

코틀린 학습. Contribute to junjange/Kotlin-Learning development by creating an account on GitHub.

github.com