본문 바로가기

[Android/Kotlin] 안드로이드 로또 당첨번호 조회하기(2)

꿈꾸는블로그왕 2021. 1. 19.

오늘은 회차별 로또 당첨번호를 가져오는 방법에서 대해서 알아보겠습니다.

 

회차별 로또번호를 조회하기 위해서는 아래 URL를 사용하시면 하시면 됩니다.

https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=946

 

검색결과 아래와 같이 json 형태로 받아 볼 수 있습니다.

{"totSellamnt":99380178000,"returnValue":"success","drwNoDate":"2021-01-16","firstWinamnt":2157656182,"drwtNo6":40,"drwtNo4":30,"firstPrzwnerCo":11,"drwtNo5":34,"bnusNo":20,"firstAccumamnt":23734218002,"drwNo":946,"drwtNo2":18,"drwtNo3":19,"drwtNo1":9}

 

이걸 토대로 회차별로 로또 당첨번호를 조회하는 방법을 소개드립니다.

 

MVVM방식을 적용해서 파일이 좀 많습니다....

 

완성된 모습은 아래와 같습니다.

 

 

STEP01. build.gradle 추가하기

    // Architectural Components
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"

    // Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation "com.squareup.okhttp3:logging-interceptor:4.5.0"

    // Coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'

 

 

STEP02. Retrofit 활용하기

Retrofit 사용법을 여기에서는 설명하지 않겠습니다.

[AndroidManifest.kt]

<uses-permission android:name="android.permission.INTERNET" />

 

[RetrofitInstance.kt]

class RetrofitInstance {

    companion object {
        private val retrofit by lazy {
            val logging = HttpLoggingInterceptor()

            logging.level = HttpLoggingInterceptor.Level.BODY

            val client = OkHttpClient.Builder()
                .addInterceptor(logging)
                .build()

            Retrofit.Builder()
                .baseUrl("https://www.dhlottery.co.kr")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build()
        }


        val api by lazy {
            retrofit.create(LottoApi::class.java)
        }
    }

}

 

[LottoApi.kt]

interface LottoApi {

    @GET("/common.do")
    suspend fun getRecentWinningNumber(
        @Query("drwNo") drwNum: Int,
        @Query("method") method: String = "getLottoNumber"
    ): Response<LottoApiModel>

}

 

[LottoApiModel.kt]

data class LottoApiModel(
    var drwNo: Int,
    var drwNoDate: String,
    var totSellamnt: Long,
    var returnValue: String,
    var firstWinamnt: Long,
    var firstPrzwnerCo: Int,
    var firstAccumamnt: Long,
    var drwtNo1: Int,
    var drwtNo2: Int,
    var drwtNo3: Int,
    var drwtNo4: Int,
    var drwtNo5: Int,
    var drwtNo6: Int,
    var bnusNo: Int
)

 

 

STEP03. Repository 생성

로또 당첨번호 조회 요청을 담당하는 Repository 파일을 하나 만들어 줍니다.

[LottoRepository.kt]

class LottoRepository {
    suspend fun getRecentWinningNumber(number: Int): Result<LottoApiModel> {
        val response = RetrofitInstance.api.getRecentWinningNumber(number)
        if (response.isSuccessful) {
            response.body()?.let {
                return Result.Success(it)
            }
        }
        return Result.Error("error")
    }
}

 

요청 결과를 Success() 또는 Error() 클래스로 리턴하도록 합니다.

[Result.kt]

sealed class Result<out T : Any> {
    data class Success<out T : Any>(val data: T) : Result<T>()
    data class Error(val error: String) : Result<Nothing>()
}

 

 

STEP04. ViewModel 생성

MainViewModel 클래스는 액티비티 대신 데이터 요청을 담당합니다.

[MainViewModel.kt]

class MainViewModel : ViewModel() {

    val lottoRepository = LottoRepository()

    private val _lottoApiResponseLiveData = MutableLiveData<LottoApiResponse>()
    val lottoApiResponseLiveData: MutableLiveData<LottoApiResponse> get() = _lottoApiResponseLiveData

    fun getRecentWinningNumber(number: Int) = viewModelScope.launch {
        _lottoApiResponseLiveData.value = LottoApiResponse.loading()

        when (val result = lottoRepository.getRecentWinningNumber(number)) {
            is Result.Success -> {
                _lottoApiResponseLiveData.value = LottoApiResponse.success(result.data)
            }
            is Result.Error -> {
                _lottoApiResponseLiveData.value = LottoApiResponse.error(result.error)
            }
        }

    }

}

 

LottoApiResponse 클래스를 만들어 요청 결과를 반환합니다.

액티비티에서 loading(), success(), error()에 따라서 유용하게 사용할 수 있습니다.

[LottoApiResponse.kt]

data class LottoApiResponse(
    val status: Status,
    val data: LottoApiModel?,
    val error: String?
) {
    companion object {
        fun loading(): LottoApiResponse = LottoApiResponse(Status.LOADING, null, null)

        fun success(lotto: LottoApiModel): LottoApiResponse =
            LottoApiResponse(Status.SUCCESS, lotto, null)

        fun error(error: String): LottoApiResponse =
            LottoApiResponse(Status.ERROR, null, error)
    }
}

 

enum class인 Status를 만들어 상태를 저장합니다.

[LottoApiResponse.kt]

enum class Status {
    LOADING,
    SUCCESS,
    ERROR
}

 

 

STEP05. 호출하기

회차를 입력하고 조회하기 버튼을 클릭하면 해당회차 로또 담청번호를 조회할 수 있습니다.

viewmodel에 정의한 lottoApiResponseLiveData를 관찰하고 그 변화에 따라 view를 변경해 줍니다.

[MainActivity.kt]

class MainActivity : AppCompatActivity() {

    private val mainViewModel by lazy {
        ViewModelProvider(this).get(MainViewModel::class.java)
    }


    private var _binding: ActivityMainBinding? = null
    private val binding get() = _binding!!

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

        binding.btnSearch.setOnClickListener {
            mainViewModel.getRecentWinningNumber(binding.edtRound.text.toString().toInt())
        }

        mainViewModel.lottoApiResponseLiveData.observe(this) { response ->
            when (response.status) {
                Status.LOADING -> {

                }
                Status.SUCCESS -> {
                    response.data?.let { lotto ->
                        binding.txtDate.text = lotto.drwNoDate
                        binding.txtNumber.text = "${lotto.drwtNo1} ${lotto.drwtNo2}  " +
                                "${lotto.drwtNo3} ${lotto.drwtNo4} ${lotto.drwtNo5} ${lotto.drwtNo6} "
                    }
                }
                Status.ERROR -> {

                }
            }

        }


    }

    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }

}

 

[activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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">

    <TextView
        android:id="@+id/txt_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:textSize="22sp"
        android:textStyle="bold"
        android:textAlignment="center"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="2021-01-16"/>

    <TextView
        android:id="@+id/txt_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:textSize="18sp"
        android:textStyle="bold"
        android:textAlignment="center"
        app:layout_constraintTop_toBottomOf="@+id/txt_date"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        tools:text="2 19 24 32 38 45"/>

    <EditText
        android:id="@+id/edt_round"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:hint="회차"
        android:inputType="number"
        app:layout_constraintTop_toBottomOf="@+id/txt_number"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/btn_search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="조회하기"
        app:layout_constraintTop_toBottomOf="@+id/edt_round"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

플레이스토어 링크: https://play.google.com/store/apps/details?id=com.reachfree.numberonelotto

 

넘버원로또(무료) - Google Play 앱

매주 행운의 주인공이 되어보세요! 당신의 슬기로운 로또생활을 응원합니다. - 넘버원 로또는 심플한 디자인으로 쉽고 직관적으로 사용할 수 있도록 했습니다. - 번호생성부터 로또 구매내역까

play.google.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

댓글