weather manager created

This commit is contained in:
JUNGGWAN KIM 2024-10-11 17:15:29 +09:00
parent 45552eacf8
commit a7dfa35e10
7 changed files with 217 additions and 93 deletions

View File

@ -421,7 +421,6 @@ internal class LauncherHome : Fragment() {
commandHandler.removeCallbacks(notiUpdate) commandHandler.removeCallbacks(notiUpdate)
commandHandler.postDelayed(notiUpdate, UPDATE_DELAY) commandHandler.postDelayed(notiUpdate, UPDATE_DELAY)
} }
else -> { else -> {
// types other than UpdatedResults are not changes -- ignore them // types other than UpdatedResults are not changes -- ignore them
} }

View File

@ -21,6 +21,7 @@ import rasel.lunar.launcher.model.Day
import rasel.lunar.launcher.model.Hour import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.Location import rasel.lunar.launcher.model.Location
import rasel.lunar.launcher.model.WeatherForcast import rasel.lunar.launcher.model.WeatherForcast
import rasel.lunar.launcher.model.WeatherInfoManager
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.WorkersDb import rasel.lunar.launcher.workers.WorkersDb
import java.time.Instant import java.time.Instant
@ -69,18 +70,20 @@ class WeatherAdapter(
// today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L) // today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L)
// val dayOfItem = today.get(Calendar.DAY_OF_YEAR) // val dayOfItem = today.get(Calendar.DAY_OF_YEAR)
data?.let { data?.let {
total.loc = WorkersDb.getRealm().query<Location>().also { // total.loc = WorkersDb.getRealm().query<Location>().also {
BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그 // BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그
}.find().first() // }.find().first()
WeatherInfoManager.getShowingInfo(it).apply {
holder.viewItem.setHour(it) total.setInfo(this)
holder.viewItem.setInfo(this)
}
BLog.LOGE("reeeeeeeeeee >>> ${holder.viewItem.hour.text}") BLog.LOGE("reeeeeeeeeee >>> ${holder.viewItem.hour.text}")
holder.viewItem.amOrPm.visibility = holder.viewItem.amOrPm.visibility =
if (arrayListOf(12, 0).contains(data.toZonedDateTime(it.time_epoch).hour) || position == 0) { if (arrayListOf(12, 0).contains(WeatherInfoManager.toZonedDateTime(it.time_epoch).hour) || position == 0) {
View.VISIBLE View.VISIBLE
} else View.INVISIBLE } else View.INVISIBLE
holder.viewItem.hour.apply { holder.viewItem.hour.apply {
if (data.toZonedDateTime(it.time_epoch).hour == 0) { if (WeatherInfoManager.toZonedDateTime(it.time_epoch).hour == 0) {
this@apply.setTextColor(Color.BLACK) this@apply.setTextColor(Color.BLACK)
this@apply.isSelected = true this@apply.isSelected = true
} else { } else {

View File

@ -20,10 +20,10 @@ class WeatherForcast: RealmObject {
var forecast: Forecast? = null var forecast: Forecast? = null
var lastUpdateTime : Long = 0L var lastUpdateTime : Long = 0L
fun readyForSaving() { // fun readyForSaving() {
lastUpdateTime = System.currentTimeMillis() // lastUpdateTime = System.currentTimeMillis()
forecast?.fill() // forecast?.fill()
} // }
} }
////////////////////////////////// //////////////////////////////////
@ -37,7 +37,7 @@ class Location: RealmObject {
var localtime_epoch = 0 var localtime_epoch = 0
var localtime: String? = null var localtime: String? = null
fun getTextLocation(): String = "$name / $country" // fun getTextLocation(): String = "$name / $country"
} }
class Current: RealmObject { class Current: RealmObject {
@ -77,11 +77,11 @@ class Forecast: RealmObject {
var forecastday: ArrayList<Forecastday> = arrayListOf() var forecastday: ArrayList<Forecastday> = arrayListOf()
var forecastdayRealm: RealmList<Forecastday> = realmListOf() var forecastdayRealm: RealmList<Forecastday> = realmListOf()
fun fill() { // fun fill() {
if (forecastdayRealm.addAll(forecastday)) { // if (forecastdayRealm.addAll(forecastday)) {
forecastdayRealm.forEach { f -> f.fill() } // forecastdayRealm.forEach { f -> f.fill() }
} // }
} // }
} }
////////////////////////////////// //////////////////////////////////
@ -102,9 +102,9 @@ class Forecastday: RealmObject {
var hour: ArrayList<Hour> = arrayListOf() var hour: ArrayList<Hour> = arrayListOf()
var hourRealm: RealmList<Hour> = realmListOf() var hourRealm: RealmList<Hour> = realmListOf()
fun fill() { // fun fill() {
hourRealm.addAll(hour) // hourRealm.addAll(hour)
} // }
} }
////////////////////////////////// //////////////////////////////////
@ -183,56 +183,56 @@ class Hour: RealmObject {
var gust_kph = 0.0 var gust_kph = 0.0
var uv = 0.0 var uv = 0.0
fun toZonedDateTime(timeEpoch: Int) = Instant.ofEpochSecond(timeEpoch.toLong()) // fun toZonedDateTime(timeEpoch: Int) = Instant.ofEpochSecond(timeEpoch.toLong())
.atZone(ZoneId.systemDefault()) // .atZone(ZoneId.systemDefault())
//
fun getAmOrPm(): String = toZonedDateTime(time_epoch).hour.run { // fun getAmOrPm(): String = toZonedDateTime(time_epoch).hour.run {
if (this < 12) "오전" else "오후" // if (this < 12) "오전" else "오후"
} // }
//
fun getTextHour(): String = toZonedDateTime(time_epoch) // fun getTextHour(): String = toZonedDateTime(time_epoch)
.run { // .run {
if (this.hour == 0) { // if (this.hour == 0) {
when (this.dayOfYear - Calendar.getInstance().get(Calendar.DAY_OF_YEAR)) { // when (this.dayOfYear - Calendar.getInstance().get(Calendar.DAY_OF_YEAR)) {
1 -> "내일" // 1 -> "내일"
2 -> "모레" // 2 -> "모레"
3 -> "글피" // 3 -> "글피"
else -> "${this.dayOfMonth}" // else -> "${this.dayOfMonth}일"
} // }
} else { // } else {
"${this.hour}" // "${this.hour}시"
} // }
} // }
//
fun getDress(): String = // fun getDress(): String =
if (temp_c >= 23) { // if (temp_c >= 23) {
"반팔" // "반팔"
} else if ((23 > temp_c) && (temp_c >= 20)) { // } else if ((23 > temp_c) && (temp_c >= 20)) {
"긴팔" // "긴팔"
} else if ((20 > temp_c) && (temp_c >= 17)) { // } else if ((20 > temp_c) && (temp_c >= 17)) {
"니트" // "니트"
} else if ((17 > temp_c) && (temp_c >= 12)) { // } else if ((17 > temp_c) && (temp_c >= 12)) {
"얇은겉옷" // "얇은겉옷"
} else if ((12 > temp_c) && (temp_c >= 6)) { // } else if ((12 > temp_c) && (temp_c >= 6)) {
"두꺼운겉옷" // "두꺼운겉옷"
} else { // } else {
"패딩" // "패딩"
} // }
//
fun getImgDress() = // fun getImgDress() =
if (temp_c >= 23) { // if (temp_c >= 23) {
R.drawable.dress_short_sleeves // R.drawable.dress_short_sleeves
} else if ((23 > temp_c) && (temp_c >= 20)) { // } else if ((23 > temp_c) && (temp_c >= 20)) {
"긴팔" // "긴팔"
} else if ((20 > temp_c) && (temp_c >= 17)) { // } else if ((20 > temp_c) && (temp_c >= 17)) {
"니트" // "니트"
} else if ((17 > temp_c) && (temp_c >= 12)) { // } else if ((17 > temp_c) && (temp_c >= 12)) {
"얇은겉옷" // "얇은겉옷"
} else if ((12 > temp_c) && (temp_c >= 6)) { // } else if ((12 > temp_c) && (temp_c >= 6)) {
"두꺼운겉옷" // "두꺼운겉옷"
} else { // } else {
"패딩" // "패딩"
} // }
//
fun getTemp(): String = "${temp_c}" // fun getTemp(): String = "${temp_c}도"
} }

View File

@ -0,0 +1,126 @@
package rasel.lunar.launcher.model
import io.realm.kotlin.ext.query
import io.realm.kotlin.types.RealmList
import rasel.lunar.launcher.R
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.OpenWeatherGetter
import rasel.lunar.launcher.workers.WorkersDb
import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime
import java.util.Calendar
class ShowingWeatherInfo() {
var textLocation: String? = null
var amOrPm: String? = null
var textHour: String? = null
var dress: String? = null
var imgDress: Int? = null
var temp: String? = null
fun setLocation(loc: Location?): ShowingWeatherInfo {
textLocation = "${loc?.name ?: "도시"} / ${loc?.country ?: "나라"}"
return this
}
fun setHour(hour: Hour): ShowingWeatherInfo {
setAmOrPm(hour)
setTextHour(hour)
setDress(hour)
setTemp(hour)
return this
}
private fun setAmOrPm(hour: Hour) = WeatherInfoManager.toZonedDateTime(hour.time_epoch).hour.run {
amOrPm = if (this < 12) "오전" else "오후"
}
private fun setTextHour(hour: Hour) {
textHour = WeatherInfoManager.toZonedDateTime(hour.time_epoch).run {
if (this.hour == 0) {
when (this.dayOfYear - Calendar.getInstance().get(Calendar.DAY_OF_YEAR)) {
1 -> "내일"
2 -> "모레"
3 -> "글피"
else -> "${this.dayOfMonth}"
}
} else {
"${this.hour}"
}
}
}
private fun setDress(hour: Hour) {
if (hour.temp_c >= 23) {
dress = "반팔"
imgDress = R.drawable.dress_short_sleeves
} else if ((23 > hour.temp_c) && (hour.temp_c >= 20)) {
dress = "긴팔"
imgDress = R.drawable.dress_long_sleeves
} else if ((20 > hour.temp_c) && (hour.temp_c >= 17)) {
dress = "니트"
imgDress = R.drawable.dress_knitwear
} else if ((17 > hour.temp_c) && (hour.temp_c >= 12)) {
dress = "얇은겉옷"
imgDress = R.drawable.dress_flimsy_outer
} else if ((12 > hour.temp_c) && (hour.temp_c >= 6)) {
dress = "두꺼운겉옷"
imgDress = R.drawable.dress_heavy_outer
} else {
dress = "패딩"
imgDress = R.drawable.dress_padded_coat
}
}
private fun setTemp(hour: Hour) {temp = "${hour.temp_c}"}
}
object WeatherInfoManager {
var info: WeatherForcast? = null
// var showingInfo: ShowingWeatherInfo? = null
// fun setInfo(data: WeatherForcast) {
// this.info = data
// BLog.LOGE("Now WeatherForcast updated. info : ${this.info}")
// }
fun readyForSaving(lat: Double, lon: Double) {
this.info?.lastUpdateTime = System.currentTimeMillis()
this.fill()
setLatitudeAndLongitude(lat, lon)
}
private fun setLatitudeAndLongitude(lat: Double, lon: Double) {
info?.forecast?.forecastdayRealm?.forEach {
it.hourRealm.forEach {h ->
h.lat = lat
h.lon = lon
}
}
}
private fun fill() {
getForecast()?.let {
if (it.forecastdayRealm.addAll(it.forecastday)) {
it.forecastdayRealm.forEach { f -> f.hourRealm.addAll(f.hour) }
}
}
}
fun toZonedDateTime(timeEpoch: Int): ZonedDateTime = Instant.ofEpochSecond(timeEpoch.toLong())
.atZone(ZoneId.systemDefault())
fun getShowingInfo(hour: Hour): ShowingWeatherInfo = ShowingWeatherInfo().setLocation(getLocation()).setHour(hour)
private fun getLocation(): Location? {
return if (info?.location == null) {
WorkersDb.getRealm().query<Location>().also {
BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그
}.find().first()
} else {
info?.location
}
}
fun getForecast(): Forecast? = info?.forecast
fun getAllForecastDay(): RealmList<Forecastday>? = getForecast()?.forecastdayRealm
fun getAllHour(day: Forecastday): RealmList<Hour> = day.hourRealm
}

View File

@ -12,6 +12,7 @@ import io.realm.kotlin.ext.asFlow
import io.realm.kotlin.ext.query import io.realm.kotlin.ext.query
import rasel.lunar.launcher.model.Hour import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.WeatherForcast import rasel.lunar.launcher.model.WeatherForcast
import rasel.lunar.launcher.model.WeatherInfoManager
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import retrofit2.Call import retrofit2.Call
import retrofit2.Retrofit import retrofit2.Retrofit
@ -64,24 +65,19 @@ class OpenWeatherGetter(context: Context, workerParams: WorkerParameters) : Base
q = "$latitude,$longitude", q = "$latitude,$longitude",
days = (System.currentTimeMillis() % 5L).toInt().toString() days = (System.currentTimeMillis() % 5L).toInt().toString()
)?.execute()?.let { response -> )?.execute()?.let { response ->
BLog.LOGE("into getWeather afterc excute") BLog.LOGE("into getWeather after execute")
BLog.LOGE("weatherApi forecast response >>> $response") BLog.LOGE("weatherApi forecast response >>> $response")
response.body()?.let { weatherInfo -> response.body()?.let { weatherInfo ->
BLog.LOGE("into getWeather on body ") WeatherInfoManager.info = weatherInfo
weatherInfo.readyForSaving() WeatherInfoManager.readyForSaving(lat ?: 0.0, lon ?: 0.0)
weatherInfo.forecast?.forecastdayRealm?.forEach {
it.hourRealm.forEach {h ->
h.lat = lat ?: 0.0
h.lon = lon ?: 0.0
}
}
// Realm에 저장 // Realm에 저장
WorkersDb.getRealm().writeBlocking { WorkersDb.getRealm().writeBlocking {
var result = copyToRealm(weatherInfo, UpdatePolicy.ALL) copyToRealm(weatherInfo, UpdatePolicy.ALL).also {
BLog.LOGE("saved weatherForcast >>> ${result}") BLog.LOGE("saved weatherForcast >>> $it")
} }
BLog.LOGE("saved weatherForcast >>> ${WorkersDb.getRealm().query<Hour>().count().find()}") }
BLog.LOGE("saved weatherForcast >>> ${WorkersDb.getRealm().query<WeatherForcast>().first().find()?.forecast?.forecastdayRealm?.size}") // BLog.LOGE("saved weatherForcast forecastdayRealm.size >>> ${WorkersDb.getRealm().query<WeatherForcast>().first().find()?.forecast?.forecastdayRealm?.size}")
// BLog.LOGE("saved weatherForcast hour.count >>> ${WorkersDb.getRealm().query<Hour>().count().find()}")
} }
} }
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout> <layout>
<data> <data>
<variable name="hour" type="rasel.lunar.launcher.model.Hour" /> <variable name="info" type="rasel.lunar.launcher.model.ShowingWeatherInfo"/>
</data> </data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp" android:layout_width="80dp"
@ -16,7 +16,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/amOrPm" android:id="@+id/amOrPm"
android:gravity="center" android:gravity="center"
android:text="@{hour.amOrPm}" android:text="@{info.amOrPm}"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:textSize="14sp" /> android:textSize="14sp" />
<TextView <TextView
@ -27,7 +27,7 @@
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:gravity="center" android:gravity="center"
android:textSize="14sp" android:textSize="14sp"
android:text="@{hour.textHour}" android:text="@{info.textHour}"
android:textAlignment="center"/> android:textAlignment="center"/>
<ImageView <ImageView
android:id="@+id/imgDress" android:id="@+id/imgDress"
@ -42,14 +42,14 @@
android:id="@+id/textDress" android:id="@+id/textDress"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:textSize="11sp" android:textSize="11sp"
android:text="@{hour.dress}" android:text="@{info.dress}"
android:gravity="center" android:gravity="center"
android:textAlignment="center"/> android:textAlignment="center"/>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/temperature" android:id="@+id/temperature"
android:text="@{hour.temp}" android:text="@{info.temp}"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:textSize="14sp" android:textSize="14sp"
android:gravity="center" android:gravity="center"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android">
<data> <data>
<variable name="loc" type="rasel.lunar.launcher.model.Location"/> <variable name="info" type="rasel.lunar.launcher.model.ShowingWeatherInfo"/>
</data> </data>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
@ -46,7 +46,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:text="@{loc.textLocation}" android:text="@{info.textLocation}"
android:textAlignment="center" android:textAlignment="center"
android:textSize="11sp" android:textSize="11sp"
android:layout_marginRight="20dp" android:layout_marginRight="20dp"