낭만 IT

반응형

이 시리즈는 간단한 기능 구현에 대한 글이며

Kotlin을 통해 개발하였고 결과물은 구글 플레이스토어에 등록하였다.
다운 받으러 가기

실제 구현 사진

관련 글 보러가기

안드로이드 마스크 앱 만들기 (1) - 공적 마스크 api와 네이버 지도 api

안드로이드 마스크 앱 만들기 (2) - GPS로 현 위치 좌표 알아내기

안드로이드 마스크 앱 만들기 (3) - 공적 마스크 api 사용하기

안드로이드 마스크 앱 만들기 (4) - 네이버 지도에 표시하기 (완결)

 

코드 다운

https://github.com/Junhwan26/MaskApp

 

Junhwan26/MaskApp

Contribute to Junhwan26/MaskApp development by creating an account on GitHub.

github.com

 


 

 

 

공적 마스크 데이터 api 바로가기

현재 위치의 좌표를 알았으니 그 좌표에 대해서 주변 약국과 마스크 재고량에 대한 정보를 받아오면 된다. 위도, 경도, 반경을 파라미터로 넘겨주면 아래와 같은 Json 형식의 데이터를 얻을 수 있다.

 

주변 판매처가 있을 경우
{  
"count": 35,  
"stores": \[{  
"addr": "서울특별시 금천구 가산디지털1로 186 109-1호 (가산동, JEI플라츠)",  
"code": "11898062",  
"created\_at": "2020/03/15 21:15:00",  
"lat": 37.4819131,  
"lng": 126.8815811,  
"name": "중앙메디칼약국",  
"remain\_stat": "empty",  
"stock\_at": "2020/03/14 11:45:00",  
"type": "01"  
},  
... 생략  
}  

 

각 각의 값들의 의미는 이렇다.

  • count : 판매처의 갯수

  • stores : 판매처 정보

    • addr : 주소

    • code : 식별 코드

    • created_at : 데이터 생성 일자

    • lat : 위도

    • lng : 경도

    • name : 이름

    • remain_stat : 재고 상태

      [100개 이상(녹색): 'plenty' / 30개 이상 100개미만(노랑색): 'some' / 2개 이상 30개 미만(빨강색): 'few' / 1개 이하(회색): 'empty' / 판매중지: 'break']

    • stock_at : 입고시간

    • type : 판매처 유형[약국: '01', 우체국: '02', 농협: '03']

 

이제 본격적인 코드를 짜보자. 먼저, Json에서 읽어온 판매처에 대한 정보를 저장한 Pharmacy 클래스를 만들어 준다. ArrayList<Pharmacy>를 다음 액티비티로 넘겨줘야 하기 때문에 Parcelable을 상속하여 작성한다.

 

"Pharmacy.kt"

class Pharmacy( val addr:String,  val latitude : Double,
                val longitude : Double,  val name : String,
                val remain_stat :String,  val stock_at : String,
                val type : String) :Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString()!!,
        parcel.readDouble(),
        parcel.readDouble(),
        parcel.readString()!!,
        parcel.readString()!!,
        parcel.readString()!!,
        parcel.readString()!!
    ) {
    }

    override fun toString(): String {
        return "$addr $latitude $longitude $name $remain_stat $stock_at $type"
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(addr)
        parcel.writeDouble(latitude)
        parcel.writeDouble(longitude)
        parcel.writeString(name)
        parcel.writeString(remain_stat)
        parcel.writeString(stock_at)
        parcel.writeString(type)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Pharmacy> {
        override fun createFromParcel(parcel: Parcel): Pharmacy {
            return Pharmacy(parcel)
        }

        override fun newArray(size: Int): Array<Pharmacy?> {
            return arrayOfNulls(size)
        }
    }
}

 

 

 

 

 

 

 

 

 

 

이제 앞에서 구한 위도와 경도를 인수로 받아 판매처의 데이터를 받아오는 함수를 만들어준다.

"MainActivity"

fun getPharmacyData(latitude:String, longitude:String, mcontext: Context) {

}

 

 

인터넷을 통해 데이터를 받아오는 작업은 비동기 처리를 해주지 않으면 에러가 발생한다. 클래스 내부에 AsyncTask를 상속받아 데이터를 받아오는 클래스를 생성해준다.

 "getPharmacyData"

 class getPharmacy : AsyncTask<Void, Void, Void>() {

            override fun doInBackground(vararg params: Void?): Void? {


            }

            override fun onPostExecute(result: Void?) {
                super.onPostExecute(result)


        }

 

 

doInBackground에서 데이터를 받아 가공하여 onPostExecute에서 판패처 데이터를 다음 액티비티로 넘겨주는 식으로 설계를 하였다.

doInBackground에서 json 형태의 판매처 데이터를 받아온다.

"getPharmacy"

                var temp: String=""
                try {
                    val stream = URL(url).openStream()
                    val read = BufferedReader(InputStreamReader(stream, "UTF-8"))
                    //temp = read.readLine()
                    var line:String?=read.readLine()
                    while(line!=null){
                        temp+=(line);
                        line=read.readLine()
                    } 

                }
                catch (e :Exception ){
                    Log.e("error",e.toString())
                }

 

 

받아온 데이터가 올바른 데이터인지 확인하는 작업이다. 올바른 데이터가 아니라면 pharmacy"none"을 넣어주고 null을 리턴한다.

"getPharmacy"

                val json = JSONObject(temp)
                try{
                    var str=json.get("message").toString()
                    pharmacy.add(Pharmacy("none", 0.0, 0.0, "none", "none", "none", "none"))

                    return null
                }
                catch (e: java.lang.Exception){
                    Log.e("Error",e.toString())
                }

 

 

올바른 데이터를 받아왔을 경우 count번 반복하여 stores리스트 안의 데이터를 pharmacy에 추가해준다.

"getPharmacy"

                val count = json.get("count").toString().toInt()
                if (count!=0) {

                    val upperArray = json.getJSONArray("stores")

                    for (i in 0..(count - 1)) {
                        val upperObject = upperArray.getJSONObject(i)
                        Log.d("CHECK",upperObject.toString())
                        pharmacy.add(Pharmacy(
                            upperObject.getString("addr"),
                            upperObject.getString("lat").toDouble(),
                            upperObject.getString("lng").toDouble(),
                            upperObject.getString("name"),
                            upperObject.getString("remain_stat"),
                            upperObject.getString("stock_at"),
                            upperObject.getString("type")
                        ))
                    }


                } else {
                    pharmacy.add(Pharmacy("none", 0.0, 0.0, "none", "none", "none", "none"))
                }

                Log.d("pharmacy",pharmacy.toString());
                return null

 

 

백그라운드의 작업이 끝났다면 onPostExecute에서 데이터를 저장한 pharmacyMapActivity로 넘겨준다. MapActivity에서 네이버 지도 위에 각각의 판매처들의 위치와 정보들을 표시하는 작업을 할 것이다.

"getPharmacyData"

            override fun onPostExecute(result: Void?) {
                super.onPostExecute(result)
                if(flag){
                    val nextIntent = Intent(mcontext, MapActivity::class.java)
                    nextIntent.putExtra("list",pharmacy)
                    nextIntent.putExtra("latitude",latitude.toDouble())
                    nextIntent.putExtra("longitude",longitude.toDouble())
                    startActivity(nextIntent)
                    finish()

                }
            }

 

 

마지막으로 getPharmacy을 실행시켜준다.

"getPharmacy"

        getPharmacy().execute()

 

 

다음 글에서는 가져온 데이터들을 네이버 지도 api를 이용하여 지도 위에 표시하는 방법에 대해 다뤄보도록 하겠다.

반응형

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band