android kotlin - Coroutines with LiveData







MainActivity.kt



package com.example.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.*
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*


class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// live data instance
val apiTime = MutableLiveData<APITime>()

// initially fetch json data
fetchJson(apiTime)

// observe the api time live data
apiTime.observe(this, Observer {
textView.text = ""
it?.apply {
textView.append(zone)
textView.append("\n\n" + date)
textView.append("\nDay of week : $dayOfWeek")
textView.append("\nWeek Number : $weekNumber")
textView.append("\nDay of year : $dayOfYear")
textView.append("\n\n" + time)
}
})

// fetch api json data
button.setOnClickListener {
fetchJson(apiTime)
}
}

// function to fetch json data from api
private fun fetchJson(apiTime: MutableLiveData<APITime>) {
lifecycleScope.launch(Dispatchers.IO) {
URL("https://worldtimeapi.org/api/timezone/Asia/Tokyo")
.openStream()
?.getString()?.apply {
apiTime.postValue(parseJson(this))
}
}
}
}


// extension function to convert input stream to string
fun InputStream.getString(): String? {
return try {
val r = BufferedReader(InputStreamReader(this))
val result = StringBuilder()
var line: String?
while (r.readLine().also { line = it } != null) {
result.append(line).appendln()
}
result.toString()
}catch (e: IOException){
e.toString()
}
}


// data class for api time
data class APITime(
val zone:String,
val date:String,
val time:String,
val dayOfWeek:Int,
val weekNumber:Int,
val dayOfYear:Int
)


// parse json data
fun parseJson(data:String):APITime{
val obj = JSONObject(data)
val timeZone = obj.getString("timezone")
val unixTime = obj.getLong("unixtime")

val date = Date(unixTime * 1000L)

val sdf = SimpleDateFormat("dd-MMM-yyyy")
sdf.timeZone = TimeZone.getTimeZone(timeZone)
val formattedDate = sdf.format(date)

val timeFormat = SimpleDateFormat("h:mm:ss a")
timeFormat.timeZone = TimeZone.getTimeZone(timeZone)
val time: String = timeFormat.format(date)

return APITime(
timeZone, // time zone
formattedDate, // full date
time, // time
obj.getInt("day_of_week"), // day of week
obj.getInt("week_number"), // week number
obj.getInt("day_of_year") // day of year
)
}





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"
android:background="#8DB600"
tools:context=".MainActivity">

<com.google.android.material.button.MaterialButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:backgroundTint="#4B5320"
android:text="Fetch API"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/textView"
style="@style/TextAppearance.MaterialComponents.Headline4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:padding="8dp"
android:gravity="center_horizontal"
android:fontFamily="sans-serif-thin"
android:textColor="#1B1811"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button"
tools:text="TextView" />

</androidx.constraintlayout.widget.ConstraintLayout>





build.gradle (app) [code to add]



dependencies {
// kotlin coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'

// life cycle
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
}









More android kotlin tutorials