print("와챠의 개발 기록장")
[안드로이드] 한국관광공사 Tour API 활용하기(지역기반 관광정보조회) - JSON 데이터 가져오기 본문
[안드로이드] 한국관광공사 Tour API 활용하기(지역기반 관광정보조회) - JSON 데이터 가져오기
minWachya 2021. 6. 23. 13:05한국관광공사 API 어떻게 쓰는지 연습을 해봤다.

이 데이터엔 상세 주소가 없어서 저렇게 나머지 부분만 나왔다.
AndroidManifest에
API 가져오고 url로 된 사진 이용하기 위해
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 추가하고
<application 안에
android:usesCleartextTraffic="true" 추가하기
blide.gradle(:app)의 dependencies에
// api 가져오기
implementation 'com.squareup.retrofit2:retrofit:2.8.0'
implementation 'com.squareup.retrofit2:converter-gson:2.8.0'
implementation 'com.github.bumptech.glide:glide:4.12.0' // 사진 가져오기
추가!!
activity_main.xml

<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout 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"> | |
<ImageView | |
android:id="@+id/imgFirstImage" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:src="@drawable/ic_launcher_foreground" | |
android:layout_weight="6"/> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical" | |
android:gravity="center" | |
android:layout_weight="4"> | |
<TextView | |
android:id="@+id/tvTitle" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="제목" | |
android:textSize="20sp" | |
android:layout_marginBottom="20dp"/> | |
<TextView | |
android:id="@+id/tvAdd1" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="주소"/> | |
<TextView | |
android:id="@+id/tvAdd2" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="상세 주소"/> | |
</LinearLayout> | |
</LinearLayout> |
TravelIntetface.kt
package com.example.mytravel | |
import retrofit2.Call | |
import retrofit2.http.GET | |
import retrofit2.http.Query | |
// 11 - [지역기반 관광정보 조회] | |
// 결과 xml파일에 접근해서 정보 가져오기 위한 요청 메시지에 필요한 것들 | |
interface TravelIntetface { | |
@GET("areaBasedList?serviceKey=서비스 키 ") | |
fun GetTravle(@Query("numOfRows") num_of_rows : Int, // 한 페이지 결과 수 | |
@Query("pageNo") page_no : Int, // 페이지 번호 | |
@Query("MobileOS") mobile_os : String, // OS 구분(필수) | |
@Query("MobileApp") mobile_app : String, // 서비스명=어플명(필수) | |
@Query("listYN") list_yn : String, // 목록 구분 | |
@Query("arrange") arrange : String, // 정렬 구분 | |
@Query("contentTypeId") content_type_id : Int, // 관광 타입ID | |
@Query("areaCode") area_code : Int, // 지역 코드 | |
@Query("sigunguCode") sigungu_code : Int, // 시군구 코드 | |
// @Query("cat1") cat1 : String, // 대분류 | |
// @Query("cat2") cat2 : String, // 중분류 | |
// @Query("cat3") cat3 : String, // 소분류 | |
// @Query("modifiedtime") modifiedtime : String, // 수정일 | |
@Query("_type") type : String) | |
: Call<TRAVEL> | |
} |
MainAvtivity.kt
package com.example.mytravel | |
import androidx.appcompat.app.AppCompatActivity | |
import android.os.Bundle | |
import android.util.Log | |
import android.widget.ImageView | |
import android.widget.TextView | |
import com.bumptech.glide.Glide | |
import com.bumptech.glide.request.RequestOptions | |
import retrofit2.Call | |
import retrofit2.Response | |
import retrofit2.Retrofit | |
import retrofit2.converter.gson.GsonConverterFactory | |
// xml 파일 형식을 data class로 구현 | |
data class TRAVEL (val response : RESPONSE) | |
data class RESPONSE(val header : HEADER, val body : BODY) | |
data class HEADER(val resultCode : String, val resultMsg : String) | |
data class BODY(val items : ITEMS, val numOfRows : String) | |
data class ITEMS(val item : ArrayList<ITEM>) // !!! 자료 1개면 배열이면 안 됨 data class ITEMS(val item : ITEM) !!! | |
// add1 : 주소, add2 : 상세 주소, title : 제목, firstimage : 사진만 가져올 거라서 이정도만! | |
data class ITEM(val addr1 : String, val addr2 : String, val title : String, val firstimage : String) | |
// retrofit을 사용하기 위한 빌더 생성 | |
private val retrofit = Retrofit.Builder() | |
.baseUrl("http://api.visitkorea.or.kr/openapi/service/rest/KorService/") | |
.addConverterFactory(GsonConverterFactory.create()) | |
.build() | |
object ApiObject { | |
val retrofitService: TravelIntetface by lazy { | |
retrofit.create(TravelIntetface::class.java) | |
} | |
} | |
class MainActivity : AppCompatActivity() { | |
val num_of_rows = 10 | |
val page_no = 1 | |
val mobile_os = "AND" | |
val mobile_app = "AppTest" | |
val list_yn = "Y" | |
val arrange = "A" | |
val content_type_id = 15 | |
val area_code = 3 | |
val sigungu_code = 4 | |
// val cat1 = "" | |
// val cat2 = "" | |
// val cat3 = "" | |
// val modifiedtime = "" | |
val type = "json" | |
lateinit var tvAdd1 : TextView | |
lateinit var tvAdd2 : TextView | |
lateinit var tvTitle : TextView | |
lateinit var imgFirstImage : ImageView | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
tvAdd1 = findViewById(R.id.tvAdd1) | |
tvAdd2 = findViewById(R.id.tvAdd2) | |
tvTitle = findViewById(R.id.tvTitle) | |
imgFirstImage = findViewById(R.id.imgFirstImage) | |
// api 가져오기 | |
setTravel() | |
} | |
// Travel 정보 가져오기 | |
fun setTravel() { | |
// 응답 자료 형식 = GetTravle(num_of_rows, page_no, mobile_os, mobile_app, | |
// list_yn, arrange, content_type_id, area_code, sigungu_code, cat1, cat2, cat3, modifiedtime) | |
val call = ApiObject.retrofitService.GetTravle(num_of_rows, page_no, mobile_os, mobile_app, | |
list_yn, arrange, content_type_id, area_code, sigungu_code, type) //, cat1, cat2, cat3, modifiedtime, type) | |
// 비동기적으로 실행하기 | |
call.enqueue(object : retrofit2.Callback<TRAVEL> { | |
// 응답 성공 시 | |
override fun onResponse(call: Call<TRAVEL>, response: Response<TRAVEL>) { | |
if (response.isSuccessful) { | |
// Travel 정보 가져오기 | |
var it: ArrayList<ITEM> = response.body()!!.response.body.items.item | |
tvTitle.text = it[2].title | |
tvAdd1.text = it[2].addr1 | |
tvAdd2.text = it[2].addr2 | |
Glide.with(imgFirstImage) | |
.load(it[2].firstimage) | |
.error(R.drawable.ic_launcher_foreground) // 오류 시 이미지 | |
.into(imgFirstImage) | |
Log.d("mmm check", response.body().toString()) | |
} | |
} | |
// 응답 실패 시 | |
override fun onFailure(call: Call<TRAVEL>, t: Throwable) { | |
Log.d("mmm", "api fail : " + t.message.toString()) | |
} | |
}) | |
} | |
} |
실행하면 맨 위 화면처럼 잘 나오긴 하는데
문제가 있다...

▲이렇게 item이 배열이면 LIST<ITEM>을 써야 받아와지고

▲이렇게 item이 배열이 아니면 ITEM으로 해야 받아와짐....^^;
어케 해결해야할까
지금 생각나는 건 TravelIntetface을 2개씩 만들어서... 하나는 Call<TRAVEL1>, 하나는 Call<TRAVEL2> 부르고
TRAVEL도 2개씩 만들고 ITEMS만 바꾸는 건데 이거 넘 비효율적인 거 같아서 고민중이다.
아... 아니면 json이 아니라 xml로 가져오는 방법도 있음...
근데 그러려면 코드 다시 짜야됨;; 일단...해보자
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[안드로이드] 갤러리에서 사진 가져오고 크롭하기(크기 조절하기) (6) | 2021.06.24 |
---|---|
[안드로이드] 한국관광공사 Tour API 활용하기(지역기반 관광정보조회) - XML 데이터 가져오기 (0) | 2021.06.23 |
[안드로이드] 스플래시 1초간 보여주기 (0) | 2021.06.13 |
[안드로이드] MediaPlayer를 이용한 음악 재생/일시정지/이어듣기/중지 (0) | 2021.05.28 |
[안드로이드] 카메라 + 사진 불러오기 (0) | 2021.05.26 |