diff --git a/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt b/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt index 0529595f..f46d2ecf 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt @@ -204,6 +204,11 @@ internal class LauncherActivity : AppCompatActivity() { }, 5, TimeUnit.SECONDS) } + fun doGetWheaterByLocationInfo() { + Executors.newSingleThreadScheduledExecutor().schedule({ + mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java)) + }, 5, TimeUnit.SECONDS) + } fun refreshFeeds() { var delay = 5L @@ -308,17 +313,19 @@ internal class LauncherActivity : AppCompatActivity() { .addTag(LocationGetter.TAG) .build()) }, weatherDelay, TimeUnit.SECONDS) - Executors.newSingleThreadScheduledExecutor().schedule({ - //de574a260b1f474d99955729241909 - mWorkManager?.cancelAllWorkByTag(OpenWeatherGetter.TAG) - mWorkManager?.enqueueUniquePeriodicWork( - OpenWeatherGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE, - PeriodicWorkRequestBuilder(midTimePeriod, TimeUnit.MINUTES) - .addTag(OpenWeatherGetter.TAG) - .build()) - }, weatherDelay + 3, TimeUnit.SECONDS) + +// Executors.newSingleThreadScheduledExecutor().schedule({ +// //de574a260b1f474d99955729241909 +// mWorkManager?.cancelAllWorkByTag(OpenWeatherGetter.TAG) +// mWorkManager?.enqueueUniquePeriodicWork( +// OpenWeatherGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE, +// PeriodicWorkRequestBuilder(midTimePeriod, TimeUnit.MINUTES) +// .addTag(OpenWeatherGetter.TAG) +// .build()) +// }, weatherDelay + 3, TimeUnit.SECONDS) } + fun workmanager() : WorkManager? { if (mWorkManager == null && lActivity != null) { mWorkManager = WorkManager.getInstance(lActivity!!) diff --git a/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt b/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt index e8e6a968..d633efd0 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt @@ -53,6 +53,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager +import io.realm.kotlin.Realm import io.realm.kotlin.ext.asFlow import io.realm.kotlin.ext.query import io.realm.kotlin.notifications.InitialObject @@ -61,12 +62,14 @@ import io.realm.kotlin.notifications.ObjectChange import io.realm.kotlin.notifications.ResultsChange import io.realm.kotlin.notifications.UpdatedObject import io.realm.kotlin.notifications.UpdatedResults +import io.realm.kotlin.query.RealmQuery import io.realm.kotlin.query.RealmResults import io.realm.kotlin.query.Sort import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import okhttp3.ConnectionPool import okhttp3.OkHttpClient @@ -93,6 +96,7 @@ import rasel.lunar.launcher.home.adapters.SmsLogsAdapter import rasel.lunar.launcher.home.adapters.WeatherAdapter import rasel.lunar.launcher.model.CurrentPlayItem import rasel.lunar.launcher.model.Hour +import rasel.lunar.launcher.model.Location import rasel.lunar.launcher.model.NotificationItem import rasel.lunar.launcher.model.RssData import rasel.lunar.launcher.model.RssDataInterface @@ -106,10 +110,13 @@ import rasel.lunar.launcher.utils.JamoUtils import rasel.lunar.launcher.utils.SimpleFingerGestures import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.view.TableRadioGroup +import rasel.lunar.launcher.workers.LocationGetter +import rasel.lunar.launcher.workers.OpenWeatherGetter import rasel.lunar.launcher.workers.RecentCall import rasel.lunar.launcher.workers.RecentSms import rasel.lunar.launcher.workers.TelegramBotGetter import rasel.lunar.launcher.workers.WorkersDb +import java.math.BigDecimal import java.net.URLEncoder import java.util.Calendar import java.util.Date @@ -294,43 +301,62 @@ internal class LauncherHome : Fragment() { } @SuppressLint("NotifyDataSetChanged") - private fun queryWeather() { - mWeatherResult = WorkersDb.getRealm().query().find() - val weatherJob = CoroutineScope(Dispatchers.Default).launch { - mWeatherResult?.asFlow()?.collect { changes -> - BLog.LOGE("saved weatherForcast >>> asFlow ${changes.list}") - if (changes.list.size > 0) { - changes.list.first().forecast?.forecastdayRealm?.let { li -> - BLog.LOGE("LauncherHome Saved Forecastdays >>> ${li.size}") - Handler(Looper.getMainLooper()).post { - mWeatherAdapter?.let{ - it.update( - mutableListOf().apply { - li.forEach { i -> - if (i == li.first()) { - this.addAll(it - .filter( - i.hourRealm.also { hli -> - BLog.LOGE("LauncherHome Saved hli size >>> ${hli.size}") - } - ).also { fli -> - BLog.LOGE("LauncherHome Saved fli size >>> ${fli.size}") - } - ) - } else { - this.addAll(i.hourRealm) - } - } - } - ) - it.notifyDataSetChanged() - } + suspend fun queryWeatherWithLoc(){ + WorkersDb.getRealm() + .query() + .query("lat == $0 AND lon == $1", + LocationGetter.latitude?.let { BigDecimal.valueOf(it).toDouble() }, + LocationGetter.longitude?.let { BigDecimal.valueOf(it).toDouble() } + ).also { + BLog.LOGE("re >>> ${it.description()}") + }.find().let {hours -> + Handler(Looper.getMainLooper()).post { + mWeatherAdapter?.let { + it.update( + mutableListOf().apply { + this.addAll(it.filter(hours)) + } + ) + it.notifyDataSetChanged() } } + } +// .asFlow() +// .collect { changes -> +// if (changes.list.size > 0) { +// Handler(Looper.getMainLooper()).post { +// mWeatherAdapter?.let { +// it.update( +// mutableListOf().apply { +// this.addAll(it.filter(changes.list)) +// } +// ) +// it.notifyDataSetChanged() +// } +// } +// } +// } + } + + var weatherJob : Job? = null + var result : RealmResults? = null + // lateinit var weatherJob : Job +// @SuppressLint("NotifyDataSetChanged") + private fun queryWeather() { + result = WorkersDb.getRealm().query().also { + BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그 + }.find() + weatherJob?.cancel() + weatherJob = CoroutineScope(Dispatchers.Default).launch { + result?.asFlow()?.collect { li -> + BLog.LOGE("queryWeather done. >>> ${li}") + if (li.list.size > 0) { + BLog.LOGE("queryWeather done. >>> ${li.list.size}") + queryWeatherWithLoc() } } } - weatherJob.start() + weatherJob?.start() } val hideListViewTime = 1000L * 60L * 15L diff --git a/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt b/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt index 1d496f87..fffd2f2d 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt @@ -2,26 +2,24 @@ package rasel.lunar.launcher.home.adapters import android.annotation.SuppressLint import android.graphics.Color -import android.support.annotation.ColorInt import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import io.realm.kotlin.ext.toRealmList import rasel.lunar.launcher.R import rasel.lunar.launcher.home.adapters.WeatherAdapter.ViewHolder -import rasel.lunar.launcher.model.Forecastday +import rasel.lunar.launcher.model.Day import rasel.lunar.launcher.model.Hour -import rasel.lunar.launcher.model.WeatherForcast import rasel.lunar.launcher.utils.BLog import java.time.Instant import java.time.ZoneId +import java.util.Calendar +import java.util.Date class WeatherAdapter(private val dataSet: ArrayList): RecyclerView.Adapter(){ var isChangedAmOrPm: Boolean = true - var day: Int = 0 class ViewHolder(view: View): RecyclerView.ViewHolder(view) { val viewItem: View @@ -54,10 +52,15 @@ class WeatherAdapter(private val dataSet: ArrayList): RecyclerView.Adapter return ViewHolder(view) } + fun getToday() = Calendar.getInstance().get(Calendar.DAY_OF_YEAR) + @SuppressLint("SetTextI18n") override fun onBindViewHolder(holder: ViewHolder, position: Int) { val data = dataSet[position] as? Hour BLog.LOGE("saved weatherForcast >>> asFlow ${dataSet.size}") +// val today = Calendar.getInstance() +// today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L) +// val dayOfItem = today.get(Calendar.DAY_OF_YEAR) data?.let { holder.viewItem.findViewById(R.id.amOrPm) .apply { @@ -75,14 +78,13 @@ class WeatherAdapter(private val dataSet: ArrayList): RecyclerView.Adapter } holder.viewItem.findViewById(R.id.hour) .apply { - this.isSelected = (System.currentTimeMillis() % 3 == 0L) Instant.ofEpochSecond(it.time_epoch.toLong()) .atZone(ZoneId.systemDefault()) .run { if (this.hour == 0) { this@apply.setTextColor(Color.BLACK) this@apply.isSelected = true - this@apply.text = when (day++) { + this@apply.text = when (this.dayOfYear - getToday()) { 1 -> "내일" 2 -> "모레" 3 -> "글피" @@ -94,13 +96,34 @@ class WeatherAdapter(private val dataSet: ArrayList): RecyclerView.Adapter this@apply.text = "${this.hour}시" } } - holder.viewItem.findViewById(R.id.imgDress) - .run { this.setImageResource(R.drawable.ico_time) } - holder.viewItem.findViewById(R.id.temperature) - .run { - this.text = "${it.temp_c}도" - } } + var img: Int? = null + var textDress: String? = null + if (it.temp_c >= 23) { + img = R.drawable.dress_short_sleeves + textDress = "반팔" + } else if ((23 > it.temp_c) && (it.temp_c >= 20)) { + img = R.drawable.dress_long_sleeves + textDress = "긴팔" + } else if ((20 > it.temp_c) && (it.temp_c >= 17)) { + img = R.drawable.dress_knitwear + textDress = "니트" + } else if ((17 > it.temp_c) && (it.temp_c >= 12)) { + img = R.drawable.dress_flimsy_outer + textDress = "얇은겉옷" + } else if ((12 > it.temp_c) && (it.temp_c >= 6)) { + img = R.drawable.dress_heavy_outer + textDress = "두꺼운겉옷" + } else { + img = R.drawable.dress_padded_coat + textDress = "패딩" + } + holder.viewItem.findViewById(R.id.imgDress) + .setImageResource(img ?: R.drawable.dress_padded_coat) + holder.viewItem.findViewById(R.id.textDress) + .text = textDress + holder.viewItem.findViewById(R.id.temperature) + .text = "${it.temp_c}도" } } diff --git a/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt b/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt index a427619d..ecbc02b2 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt @@ -8,11 +8,16 @@ import io.realm.kotlin.types.annotations.PrimaryKey class WeatherForcast: RealmObject { + @PrimaryKey + var isOnlyKey = "isOnlyKey" + var location: Location? = null var current: Current? = null var forecast: Forecast? = null + var lastUpdateTime : Long = 0L fun readyForSaving() { + lastUpdateTime = System.currentTimeMillis() forecast?.fill() } } @@ -133,6 +138,9 @@ class Astro: RealmObject { } class Hour: RealmObject { + var lat : Double = 0.0 + var lon : Double = 0.0 + @PrimaryKey var time_epoch = 0 var time: String? = null diff --git a/app/src/main/kotlin/rasel/lunar/launcher/workers/LocationGetter.kt b/app/src/main/kotlin/rasel/lunar/launcher/workers/LocationGetter.kt index dfa133fc..511828b0 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/workers/LocationGetter.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/workers/LocationGetter.kt @@ -7,6 +7,7 @@ import androidx.work.WorkerParameters import com.google.android.gms.location.LocationServices import com.google.android.gms.location.Priority import com.google.android.gms.tasks.CancellationTokenSource +import rasel.lunar.launcher.LauncherActivity.Companion.doGetWheaterByLocationInfo import rasel.lunar.launcher.utils.BLog class LocationGetter(context: Context, workerParams: WorkerParameters) : BaseGetter(context, workerParams) { @@ -28,6 +29,7 @@ class LocationGetter(context: Context, workerParams: WorkerParameters) : BaseGet BLog.LOGE("Location >>> (latitude)${it.longitude}/(longitude)${it.latitude}") longitude = it.longitude latitude = it.latitude + doGetWheaterByLocationInfo() } }.addOnFailureListener{ BLog.LOGE("Location error >>> $it") diff --git a/app/src/main/kotlin/rasel/lunar/launcher/workers/OpenWeatherGetter.kt b/app/src/main/kotlin/rasel/lunar/launcher/workers/OpenWeatherGetter.kt index e564d8f6..ffa8dfcf 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/workers/OpenWeatherGetter.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/workers/OpenWeatherGetter.kt @@ -8,7 +8,9 @@ import com.google.android.gms.location.LocationServices import com.google.android.gms.location.Priority import com.google.android.gms.tasks.CancellationTokenSource import io.realm.kotlin.UpdatePolicy +import io.realm.kotlin.ext.asFlow import io.realm.kotlin.ext.query +import rasel.lunar.launcher.model.Hour import rasel.lunar.launcher.model.WeatherForcast import rasel.lunar.launcher.utils.BLog import retrofit2.Call @@ -22,16 +24,17 @@ import retrofit2.http.Query class OpenWeatherGetter(context: Context, workerParams: WorkerParameters) : BaseGetter(context, workerParams) { companion object { val TAG = "OpenWeatherGetter" + var lon: Double? = null // 경도 + var lat: Double? = null // 위도 } ////////////////////////////////////////// // weatherapi val VER_WEATHERAPI = "v1" val URI_WEATHERAPI = "https://api.weatherapi.com" val KEY_WEATHERAPI = "8133d83d23ab4175a4160624241909" - val DAYS = 2 + val DAYS = 3 ////////////////////////////////////////// - var lon: Double? = null // 경도 - var lat: Double? = null // 위도 + ////////////////////////////////////////// override fun realWork(): Result { @@ -48,6 +51,8 @@ class OpenWeatherGetter(context: Context, workerParams: WorkerParameters) : Base } fun getWeather(latitude: Double, longitude: Double) { + BLog.LOGE("into getWeather") + ///saved weatherForcast Retrofit.Builder() .baseUrl(URI_WEATHERAPI) .addConverterFactory(GsonConverterFactory.create()) @@ -57,16 +62,26 @@ class OpenWeatherGetter(context: Context, workerParams: WorkerParameters) : Base ver = VER_WEATHERAPI, key = KEY_WEATHERAPI, q = "$latitude,$longitude", - days = DAYS.toString() + days = (System.currentTimeMillis() % 5L).toInt().toString() )?.execute()?.let { response -> + BLog.LOGE("into getWeather afterc excute") BLog.LOGE("weatherApi forecast response >>> $response") response.body()?.let { weatherInfo -> + BLog.LOGE("into getWeather on body ") + weatherInfo.readyForSaving() + weatherInfo.forecast?.forecastdayRealm?.forEach { + it.hourRealm.forEach {h -> + h.lat = lat ?: 0.0 + h.lon = lon ?: 0.0 + } + } // Realm에 저장 WorkersDb.getRealm().writeBlocking { - weatherInfo.readyForSaving() - copyToRealm(weatherInfo, UpdatePolicy.ALL) + var result = copyToRealm(weatherInfo, UpdatePolicy.ALL) + BLog.LOGE("saved weatherForcast >>> ${result}") } - BLog.LOGE("saved weatherForcast >>> ${WorkersDb.getRealm().query().first().find()}") + BLog.LOGE("saved weatherForcast >>> ${WorkersDb.getRealm().query().count().find()}") + BLog.LOGE("saved weatherForcast >>> ${WorkersDb.getRealm().query().first().find()?.forecast?.forecastdayRealm?.size}") } } } diff --git a/app/src/main/res/drawable-nodpi/dress_flimsy_outer.png b/app/src/main/res/drawable-nodpi/dress_flimsy_outer.png new file mode 100644 index 00000000..b0cd9dfb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dress_flimsy_outer.png differ diff --git a/app/src/main/res/drawable-nodpi/dress_heavy_outer.png b/app/src/main/res/drawable-nodpi/dress_heavy_outer.png new file mode 100644 index 00000000..ca3d8a62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dress_heavy_outer.png differ diff --git a/app/src/main/res/drawable-nodpi/dress_knitwear.png b/app/src/main/res/drawable-nodpi/dress_knitwear.png new file mode 100644 index 00000000..670e8c66 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dress_knitwear.png differ diff --git a/app/src/main/res/drawable-nodpi/dress_long_sleeves.png b/app/src/main/res/drawable-nodpi/dress_long_sleeves.png new file mode 100644 index 00000000..0ebbc00b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dress_long_sleeves.png differ diff --git a/app/src/main/res/drawable-nodpi/dress_padded_coat.png b/app/src/main/res/drawable-nodpi/dress_padded_coat.png new file mode 100644 index 00000000..7c6a3466 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dress_padded_coat.png differ diff --git a/app/src/main/res/drawable-nodpi/dress_short_sleeves.png b/app/src/main/res/drawable-nodpi/dress_short_sleeves.png new file mode 100644 index 00000000..9d6f1e9d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dress_short_sleeves.png differ diff --git a/app/src/main/res/layout/item_rec_hourly_dress.xml b/app/src/main/res/layout/item_rec_hourly_dress.xml index 8a50a12a..3303be59 100644 --- a/app/src/main/res/layout/item_rec_hourly_dress.xml +++ b/app/src/main/res/layout/item_rec_hourly_dress.xml @@ -10,7 +10,6 @@ + android:contentDescription="온도별 옷차림" + app:tint="@android:color/white"/> + - \ No newline at end of file diff --git a/app/src/main/res/layout/recommended_hourly_dress.xml b/app/src/main/res/layout/recommended_hourly_dress.xml index af531b39..50db6d7f 100644 --- a/app/src/main/res/layout/recommended_hourly_dress.xml +++ b/app/src/main/res/layout/recommended_hourly_dress.xml @@ -21,7 +21,8 @@ android:contentDescription="시계 아이콘" app:srcCompat="@drawable/ico_time" tools:ignore="ImageContrastCheck" - android:layout_marginLeft="20dp"/> + android:layout_marginLeft="20dp" + app:tint="@android:color/white" />