와챠의 우당탕탕 코딩 일기장
[안드로이드] 기상청 동네예보 API 활용하기 본문
아래의 앱을 만들어 볼 것이다.
원래는 흰 배경에 검정 글씨인데
지금 내 폰이 다크모드라 저렇게 됐다. 신기...
공공 데이터 포탈에서 아래 API를 검색한 후 활용 신청하기!!
AndroidManifest.xml 설정하기
1)
manifest-application에
android:usesCleartextTraffic="true" 추가
2)
인터넷과 네트워크 연결 위해서 아래의 퍼미션
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
추가
그러면 일케 된다.
AndroidManifest.xml
grable(:app) 설정하기
implementation 'com.squareup.retrofit2:retrofit:2.8.0'
implementation 'com.squareup.retrofit2:converter-gson:2.8.0'
추가!
일단 코드 먼저... 자세한 설명은 마지막에
activity_main.xml
WeatherInterface.kt
MainActivity.kt
1, MainActivity에서 32번째 줄에 사용된 링크는 공공 데이터 포탈에서 아래 주소를 복붙하면 된다.
baseUrl("http://apis.data.go.kr/1360000/VilageFcstInfoService/")
2, 나는 이중에 "동네 예보 조회"를 사용할 것이기 때문에 WeatherInterface의 10번째 줄에서 getVilageFcst를 적었다.
@GET("getVilageFcst?serviceKey=D")
3, 데이터를 요청할 때 아래의 정보가 필요한데 이 작업은 WeatherInterface에서 한다.
4, 요청받은 데이터는 아래의 응답을 주는데, 나는 노란 밑줄친 부분만 필요해서 MainActivity에
data class ITEM(val category : String, val fcstDate : String, val fcstTime : String, val fcstValue : String)
위와 같이 적었다.
5, 응답 메시지의 xml은 아래와 같은데 이를 data class로 표현해주기 위해 아래와 같이 표현했다.
태그의 관계를 잘 살펴보면 이해하기 쉽다!
response 안에 header, body가 있고...heraer 안에 resultCode와 resultMsg가 있고... 이런 식이다.
data class WEATHER (val response : RESPONSE)
data class RESPONSE(val header : HEADER, val body : BODY)
data class HEADER(val resultCode : Int, val resultMsg : String)
data class BODY(val dataType : String, val items : ITEMS)
data class ITEMS(val item : List<ITEM>)
6, item에는 아래의 정보가 담겨져 오는데, 나는 노란색 부분만 필요해서
이렇게 표현해줬다.
for (i in 0..9) {
when(it[i].category) {
"POP" -> rainRatio = it[i].fcstValue // 강수 기온
"PTY" -> rainType = it[i].fcstValue // 강수 형태
"REH" -> humidity = it[i].fcstValue // 습도
"SKY" -> sky = it[i].fcstValue // 하늘 상태
"T3H" -> temp = it[i].fcstValue // 기온
else -> continue
}
}
7, 아래의 정보로 강수 형태와 하늘 상태에 대한 string값을 정했다.
// 강수 형태
when(rainType) {
"0" -> result = "없음"
"1" -> result = "비"
"2" -> result = "비/눈"
"3" -> result = "눈"
"4" -> result = "소나기"
"5" -> result = "빗방울"
"6" -> result = "빗방울/눈날림"
"7" -> result = "눈날림"
else -> "오류"
}
// 하늘 상태
when(sky) {
"1" -> result = "맑음"
"3" -> result = "구름 많음"
"4" -> result = "흐림"
else -> "오류"
}
8, 그리고 가장 헷갈렸던 건데 이 baseTime(예보자료 시각)과 fcstTime(발표 시간),,,
아래의 표를 보면 "발표시간 = 현재 시각 + 4"이란 것을 할 수 있다.
그니끼 현재 시간으로 데이터를 요청하면 현재시간대 + 4시간의 예보를 얻을 수 있는 것이다.
ex) 현재 시각이 0200이면, +4시간이 된 0600의 예보를 받음
(2시 예보가 아닌 6시의 예보를 미리 받는 것)
그런데 나는 다음 시간대의 예보를 미리 받아보고 싶은 게 아닌 현재 시간대의 예보를 알고 싶어서 아래의 함수로 설정을 다시 해줬다.
만약 내가 6~8시 사이에 있고 6시 예보를 받고 싶다면 4시간 전인 2시로 baseTime을 설정해주어야 함...을 나타내는 표
base time | fcst time | 현재 시간대 |
0200 | 0600 | 06~08 |
0500 | 0900 | 09~11 |
0800 | 1200 | 12~14 |
1100 | 1500 | 15~17 |
1400 | 1800 | 18~20 |
1700 | 2100 | 21~23 |
2000 | 0000 | 00~02 |
2300 | 0300 | 03~05 |
fun getTime(time : String) : String {
var result = ""
when(time) {
in "00".."02" -> result = "2000" // 00~02
in "03".."05" -> result = "2300" // 03~05
in "06".."08" -> result = "0200" // 06~08
in "09".."11" -> result = "0500" // 09~11
in "12".."14" -> result = "0800" // 12~14
in "15".."17" -> result = "1100" // 15~17
in "18".."20" -> result = "1400" // 18~20
else -> result = "1700" // 21~23
}
return result
}
그리고 현재 시각에 대한 정보를 얻으려면 현재시각 + 4시간을 해야하다보니까
오늘의 예보시각(fcst time) 0000의 예보를 보기 위해선 어제의 현재시각(base time) 2000 예보가 필요하다,,,
위 표의 이부분
base time (현재 시각) | fcst time (예보 시각) |
20000 | 0000 |
2300 | 0300 |
그래서 base_date도 하루를 빼주는....^^!!!
if (base_time >= "2000") {
cal.add(Calendar.DATE, -1).toString()
base_date = SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(cal.time)
}
API 써보니까 넘 재밌다...
별 거 안 했는데 유용한 정보가 쏙쏙 나오는 이 기분...
땅을 팠는데... 고구마가 나온 기분
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[안드로이드] 웹 크롤링 (0) | 2021.05.14 |
---|---|
[안드로이드] 안드로이드 XML 데이터 파싱 (0) | 2021.05.14 |
[안드로이드] 카카오 로그인(2) (0) | 2021.05.07 |
[안드로이드] 카카오 로그인 api(1) (0) | 2021.05.07 |
[안드로이드] Firebase 연동(2) (0) | 2021.05.06 |