Strong 감자의 공부

Volley이용해 JSON 날씨 받아오기 -Kotlin 본문

앱개발/졸업작품 with Kotlin

Volley이용해 JSON 날씨 받아오기 -Kotlin

ugyeong 2023. 3. 27. 11:58

전에 작성한 날씨API부분을 다른곳에 활용할 때가 되어 코드를 다시보게 되었다. 솔직히 그 당시에 무작정 다른 블로그 보고 따라 작성했다. 그래서 Volley에 대해 잘 모른채로 넘어갔는데 이번 기회에 정리 해보려한다.

 

스타토~ 😊


▪️ Volley의 장점-> https://developer.android.com/training/volley?hl=ko

+ Volley는 파싱하는 동안 모든 응답을 메모리에 유지하기에 대규모 다운로드, 스트리밍에는 사용하지 말것(이 경우에는 DownloadManager이용)

 

▪️ Volley 작동방식

Volley의 작동 구조는 먼저 Request 요청객체를 만들고 이 요청객체를 requestQueue(요청 큐)에 넣어주면 이 requestQueue가 자동으로 웹서버에 요청을 해주고 응답을 받아 사용자가 사용할 수 있게 지정된 메소드를 호출해줍니다.
출처: https://velog.io/@dlrmwl15/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-Volley%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-HTTP-%ED%86%B5%EC%8B%A0

▪️ 사용한 날씨 API 사이트 https://openweathermap.org/api

   1. 회원가입 -> 상단 내 아이디를 클릭-> My API keys 클릭 -> Create Key (키 이름은 구분되는걸로 맘대로)

 

   2. 내가 필요한 날씨는 시(City) 정도 였고 분당 60번 호출 달에 1,000,000이면 충분했다.

       그래서 나는 Current & Forecast weather data collection

       의 Current Weather Data를 사용하였고 그 중 하단 방식

       (그림1)으로 불러왔다. 

 

참고)

1. API키 발급 받은 후 좀 기다려야 날씨 정보를 받아 올 수 있다. 

2. 무료 호출 횟수 & 유료범위 확인 :  https://openweathermap.org/price

그림 1
그림 2

여기서 내가 필요한것은 JSONObject의 "weather" 배열 [0] 중 "description"의 clear sky이다. 즉 노란줄입니다.

아래 코드 작성시 한번 더 들여다 봐야한다. (+ JSON에 대해 자세히 설명해둔 블로그 : https://onlyformylittlefox.tistory.com/7)

▪️  사용한 파일 및 설명

Volley 사용위해 먼저 설정할 파일들

  • Gradle Scripts-build.gradle(Module:app)- >dependencies{ }안에 하단 코드 적기 -> Sync Now 클릭 
dependencies {
// ...
implementation 'com.android.volley:volley:1.2.1'
// ...
}
  • app- manifest-AndroidManifest.xml-> manifest 태그 안에 #1추가,  application태그 안에 #2  추가
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.incheon_weather">
    <uses-permission android:name="android.permission.INTERNET"/> // #1 앱에 인터넷 권한추가
<application
//...
        android:usesCleartextTraffic="true" // #2 Http통신 허용
//...
        >

//...
</application>

 

  • activity_main_xml : 확인용 xml
  • MainActivity.kt : api사용 코드

▪️  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="wrap_content"
    android:layout_gravity="center_vertical"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/dateView" // 월 표시
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="dateview"
        android:textSize="40sp"
        android:padding="20dp"/>

    <TextView
        android:id="@+id/weatherView" // 날씨 표시
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:padding="20dp"
        android:text="weatherview"
        android:textSize="40sp"/>
    <Button
        android:id="@+id/Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Click"
        android:textSize="40sp"/>

</LinearLayout>

 

▪️ MainActivity.kt

package com.example.exper

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.AuthFailureError
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import com.example.exper.databinding.ActivityMainBinding
import org.json.JSONException
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {
    companion object {
        var requestQueue: RequestQueue? = null
    }
    private lateinit var binding  : ActivityMainBinding
    var weatherView: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding=ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(applicationContext) // requestqueue 객체 만들기
        }
        val button = binding.Button
        val dateView = binding.dateView
        weatherView = binding.weatherView

        button.setOnClickListener {
            // 월 가져오기
            val now = System.currentTimeMillis()
            val date = Date(now)
            val simpleDateFormatDay = SimpleDateFormat("MM")
            val getMonth = simpleDateFormatDay.format(date)
            val getDate = """
                $getMonth
                
                """.trimIndent() // 공통으로 들어있는 들여쓰기 제거

            CurrentWeatherCall() // 날씨 호출

            if (getMonth == "12" || getMonth == "01" || getMonth == "02") dateView.text = "겨울"
            else if (getMonth == "03" || getMonth == "04" || getMonth == "05") dateView.text = "봄"
            else if (getMonth == "06" || getMonth == "07" || getMonth == "08") dateView.text = "여름"
            else dateView.text = "가을"
        }
    }

    private fun CurrentWeatherCall() {
        val url =
            "https://api.openweathermap.org/data/2.5/weather?q=Incheon&appid= 개인 키입력" // 인천 지역 날씨 받아오기
        val request = object : StringRequest(
            Request.Method.GET,
            url,
            Response.Listener { response ->
                try {
                    // JSON 데이터 가져오기
                    val jsonObject = JSONObject(response)
                    val weatherJson = jsonObject.getJSONArray("weather")
                    val weatherObj = weatherJson.getJSONObject(0)
                    val weather = weatherObj.getString("description")
                    if (weather.contains("rain")) weatherView!!.text = "비"
                    else if (weather.contains("snow")) weatherView!!.text = "눈"
                    else weatherView!!.text = "맑음"
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            },
            Response.ErrorListener { }) {
//            @Throws(AuthFailureError::class)
//            override fun getParams(): Map<String, String>? { // 서버에 데이터 보낼 시
//                return HashMap()
//            }
        }
        request.setShouldCache(false) // 이전 결과가 있어도 새 요청하여 결과 보여주기
        requestQueue!!.add(request)
    }
}

Volley 라이브러리 : 구글에서 제공하는 HTTP통신 라이브러리

GET방식 POST 방식
서버로부터 데이터 받고 싶을 때 사용 서버에 데이터 보낼 때 사용

문자열 데이터 요청 -> StringRequst()

StringRequst (GET, POST 방식결정, URL, 서버응답시 처리할 내용(Listener), 응답 실패 시 처리할 내용(Listener))

 

참고)

Get Post방식 : https://hwiyong.tistory.com/18  

Volley 사용및 동작 : https://developer.android.com/training/volley/simple?hl=ko 

JAVA 코드: https://wikidocs.net/107909