From 6ed6d18f5be31abb9d49017ee0eb199d28670596 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Wed, 17 Jan 2024 22:40:34 -0500 Subject: [PATCH 1/9] Settings: ensure personal key is enabled after entering key --- .../com/thewizrd/simpleweather/preferences/SettingsFragment.kt | 1 + .../com/thewizrd/simpleweather/setup/SetupProviderFragment.kt | 1 + .../com/thewizrd/simpleweather/preferences/SettingsActivity.kt | 1 + 3 files changed, 3 insertions(+) diff --git a/app/src/main/java/com/thewizrd/simpleweather/preferences/SettingsFragment.kt b/app/src/main/java/com/thewizrd/simpleweather/preferences/SettingsFragment.kt index 62267a89d..6c9a5ed16 100644 --- a/app/src/main/java/com/thewizrd/simpleweather/preferences/SettingsFragment.kt +++ b/app/src/main/java/com/thewizrd/simpleweather/preferences/SettingsFragment.kt @@ -814,6 +814,7 @@ class SettingsFragment : BaseSettingsFragment(), settingsManager.setAPIKey(provider, key) settingsManager.setAPI(provider) settingsManager.setKeyVerified(provider, true) + settingsManager.setPersonalKey(true) updateKeySummary() diff --git a/app/src/main/java/com/thewizrd/simpleweather/setup/SetupProviderFragment.kt b/app/src/main/java/com/thewizrd/simpleweather/setup/SetupProviderFragment.kt index e9219015d..bf1a481c5 100644 --- a/app/src/main/java/com/thewizrd/simpleweather/setup/SetupProviderFragment.kt +++ b/app/src/main/java/com/thewizrd/simpleweather/setup/SetupProviderFragment.kt @@ -254,6 +254,7 @@ class SetupProviderFragment : CustomPreferenceFragmentCompat(), StepperFragment settingsManager.setAPIKey(provider, key) settingsManager.setAPI(provider) settingsManager.setKeyVerified(provider, true) + settingsManager.setPersonalKey(true) updateKeySummary() diff --git a/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/SettingsActivity.kt b/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/SettingsActivity.kt index 334c81762..184449f46 100644 --- a/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/SettingsActivity.kt +++ b/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/SettingsActivity.kt @@ -669,6 +669,7 @@ class SettingsActivity : WearableListenerActivity() { settingsManager.setAPIKey(provider, key) settingsManager.setAPI(provider) settingsManager.setKeyVerified(provider, true) + settingsManager.setPersonalKey(true) updateKeySummary() From 78d81b9964c3113f4c44687e4282237d3d80ca88 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Wed, 17 Jan 2024 22:48:21 -0500 Subject: [PATCH 2/9] MetnoWeatherProvider: update sunrise api * sunrise 2.0 is decommissioned --- .../common/controls/WeatherUiModel.kt | 78 +++---- .../thewizrd/weather_api/metno/AstroCommon.kt | 11 + .../thewizrd/weather_api/metno/AstroMeta.java | 19 -- .../weather_api/metno/AstroResponse.java | 30 --- .../thewizrd/weather_api/metno/HighMoon.java | 41 ---- .../thewizrd/weather_api/metno/Location.java | 54 ----- .../thewizrd/weather_api/metno/LowMoon.java | 41 ---- .../weather_api/metno/MetnoWeatherProvider.kt | 205 ++++++++++++------ .../weather_api/metno/MoonResponse.kt | 94 ++++++++ .../thewizrd/weather_api/metno/Moonphase.java | 41 ---- .../weather_api/metno/Moonposition.java | 74 ------- .../thewizrd/weather_api/metno/Moonrise.java | 30 --- .../thewizrd/weather_api/metno/Moonset.java | 30 --- .../weather_api/metno/Moonshadow.java | 52 ----- .../weather_api/metno/Solarmidnight.java | 41 ---- .../thewizrd/weather_api/metno/Solarnoon.java | 41 ---- .../thewizrd/weather_api/metno/SunResponse.kt | 91 ++++++++ .../thewizrd/weather_api/metno/Sunrise.java | 30 --- .../thewizrd/weather_api/metno/Sunset.java | 30 --- .../thewizrd/weather_api/metno/TimeItem.java | 140 ------------ .../thewizrd/weather_api/metno/WeatherData.kt | 107 +++++---- 21 files changed, 424 insertions(+), 856 deletions(-) create mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroCommon.kt delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroMeta.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroResponse.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/HighMoon.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Location.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/LowMoon.java create mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/MoonResponse.kt delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonphase.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonposition.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonrise.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonset.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonshadow.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarmidnight.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarnoon.java create mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/SunResponse.kt delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunrise.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunset.java delete mode 100644 weather-api/src/main/java/com/thewizrd/weather_api/metno/TimeItem.java diff --git a/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt b/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt index 45250b20b..aaafcee7b 100644 --- a/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt +++ b/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt @@ -551,62 +551,44 @@ class WeatherUiModel() { // Astronomy if (weatherData?.astronomy != null) { - sunPhase = SunPhaseViewModel(weatherData!!.astronomy, weatherData!!.location.tzOffset) + val astroTimeFormatter = if (DateFormat.is24HourFormat(sharedDeps.context)) { + DateTimeUtils.ofPatternForInvariantLocale(DateTimeConstants.CLOCK_FORMAT_24HR); + } else { + DateTimeUtils.ofPatternForInvariantLocale(DateTimeConstants.CLOCK_FORMAT_12HR_AMPM); + } - weatherDetailsMap[WeatherDetailsType.SUNRISE] = - DetailItemViewModel(WeatherDetailsType.SUNRISE, sunPhase!!.sunrise) - weatherDetailsMap[WeatherDetailsType.SUNSET] = - DetailItemViewModel(WeatherDetailsType.SUNSET, sunPhase!!.sunset) + if (weatherData?.astronomy?.sunrise != null && weatherData?.astronomy?.sunset != null) { + sunPhase = + SunPhaseViewModel(weatherData!!.astronomy, weatherData!!.location.tzOffset) + } - moonPhase = MoonPhaseViewModel(weatherData!!.astronomy) + weatherData?.astronomy?.sunrise?.let { + weatherDetailsMap[WeatherDetailsType.SUNRISE] = + DetailItemViewModel(WeatherDetailsType.SUNRISE, astroTimeFormatter.format(it)) + } + weatherData?.astronomy?.sunset?.let { + weatherDetailsMap[WeatherDetailsType.SUNSET] = + DetailItemViewModel(WeatherDetailsType.SUNSET, astroTimeFormatter.format(it)) + } if (weatherData?.astronomy?.moonrise != null && weatherData?.astronomy?.moonset != null) { - if (DateFormat.is24HourFormat(context)) { - if (weatherData!!.astronomy.moonrise.isAfter(DateTimeUtils.LOCALDATETIME_MIN)) { - weatherDetailsMap[WeatherDetailsType.MOONRISE] = DetailItemViewModel( - WeatherDetailsType.MOONRISE, - weatherData!!.astronomy.moonrise.format( - DateTimeUtils.ofPatternForUserLocale( - DateTimeConstants.CLOCK_FORMAT_24HR - ) - ) - ) - } - if (weatherData!!.astronomy.moonset.isAfter(DateTimeUtils.LOCALDATETIME_MIN)) { - weatherDetailsMap[WeatherDetailsType.MOONSET] = DetailItemViewModel( - WeatherDetailsType.MOONSET, - weatherData!!.astronomy.moonset.format( - DateTimeUtils.ofPatternForUserLocale( - DateTimeConstants.CLOCK_FORMAT_24HR - ) - ) - ) - } - } else { - if (weatherData!!.astronomy.moonrise.isAfter(DateTimeUtils.LOCALDATETIME_MIN)) { - weatherDetailsMap[WeatherDetailsType.MOONRISE] = DetailItemViewModel( - WeatherDetailsType.MOONRISE, - weatherData!!.astronomy.moonrise.format( - DateTimeUtils.ofPatternForUserLocale( - DateTimeConstants.CLOCK_FORMAT_12HR_AMPM - ) - ) - ) - } - if (weatherData!!.astronomy.moonset.isAfter(DateTimeUtils.LOCALDATETIME_MIN)) { - weatherDetailsMap[WeatherDetailsType.MOONSET] = DetailItemViewModel( - WeatherDetailsType.MOONSET, - weatherData!!.astronomy.moonset.format( - DateTimeUtils.ofPatternForUserLocale( - DateTimeConstants.CLOCK_FORMAT_12HR_AMPM - ) - ) - ) - } + if (weatherData!!.astronomy.moonrise.isAfter(DateTimeUtils.LOCALDATETIME_MIN)) { + weatherDetailsMap[WeatherDetailsType.MOONRISE] = DetailItemViewModel( + WeatherDetailsType.MOONRISE, + weatherData!!.astronomy.moonrise.format(astroTimeFormatter) + ) + } + if (weatherData!!.astronomy.moonset.isAfter(DateTimeUtils.LOCALDATETIME_MIN)) { + weatherDetailsMap[WeatherDetailsType.MOONSET] = DetailItemViewModel( + WeatherDetailsType.MOONSET, + weatherData!!.astronomy.moonset.format(astroTimeFormatter) + ) } } if (weatherData?.astronomy?.moonPhase != null) { + moonPhase = MoonPhaseViewModel(weatherData!!.astronomy) + if (!isPhone) { weatherDetailsMap[WeatherDetailsType.MOONPHASE] = DetailItemViewModel(weatherData!!.astronomy.moonPhase.phase) diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroCommon.kt b/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroCommon.kt new file mode 100644 index 000000000..6b7384863 --- /dev/null +++ b/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroCommon.kt @@ -0,0 +1,11 @@ +package com.thewizrd.weather_api.metno + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class When( + + @Json(name = "interval") + val interval: List? = null +) \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroMeta.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroMeta.java deleted file mode 100644 index ab86d7dcb..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroMeta.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class AstroMeta { - - @Json(name = "licenseurl") - private String licenseurl; - - public void setLicenseurl(String licenseurl) { - this.licenseurl = licenseurl; - } - - public String getLicenseurl() { - return licenseurl; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroResponse.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroResponse.java deleted file mode 100644 index 339d1621a..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/AstroResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class AstroResponse { - - @Json(name = "meta") - private AstroMeta meta; - - @Json(name = "location") - private Location location; - - public void setMeta(AstroMeta meta) { - this.meta = meta; - } - - public AstroMeta getMeta() { - return meta; - } - - public void setLocation(Location location) { - this.location = location; - } - - public Location getLocation() { - return location; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/HighMoon.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/HighMoon.java deleted file mode 100644 index 5fd167aa1..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/HighMoon.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class HighMoon { - - @Json(name = "elevation") - private String elevation; - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getElevation() { - return elevation; - } - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Location.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Location.java deleted file mode 100644 index 74e57649e..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Location.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -import java.util.List; - -@JsonClass(generateAdapter = true, generator = "java") -public class Location { - - @Json(name = "latitude") - private String latitude; - - @Json(name = "time") - private List time; - - @Json(name = "height") - private String height; - - @Json(name = "longitude") - private String longitude; - - public void setLatitude(String latitude) { - this.latitude = latitude; - } - - public String getLatitude() { - return latitude; - } - - public void setTime(List time) { - this.time = time; - } - - public List getTime() { - return time; - } - - public void setHeight(String height) { - this.height = height; - } - - public String getHeight() { - return height; - } - - public void setLongitude(String longitude) { - this.longitude = longitude; - } - - public String getLongitude() { - return longitude; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/LowMoon.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/LowMoon.java deleted file mode 100644 index decd45647..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/LowMoon.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class LowMoon { - - @Json(name = "elevation") - private String elevation; - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getElevation() { - return elevation; - } - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/MetnoWeatherProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/metno/MetnoWeatherProvider.kt index e4b709449..3c75079c7 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/MetnoWeatherProvider.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/metno/MetnoWeatherProvider.kt @@ -37,8 +37,12 @@ import java.util.concurrent.TimeUnit class MetnoWeatherProvider : WeatherProviderImpl() { companion object { - private const val FORECAST_QUERY_URL = "https://api.met.no/weatherapi/locationforecast/2.0/complete.json?%s" - private const val SUNRISE_QUERY_URL = "https://api.met.no/weatherapi/sunrise/2.0/.json?%s&date=%s&offset=+00:00" + private const val FORECAST_QUERY_URL = + "https://api.met.no/weatherapi/locationforecast/2.0/complete.json?%s" + private const val SUN_QUERY_URL = + "https://api.met.no/weatherapi/sunrise/3.0/sun?%s&date=%s&offset=+00:00" + private const val MOON_QUERY_URL = + "https://api.met.no/weatherapi/sunrise/3.0/moon?%s&date=%s&offset=+00:00" private fun getNeutralIconName(icon_variant: String?): String { return icon_variant?.replace("_day", "") @@ -86,7 +90,8 @@ class MetnoWeatherProvider : WeatherProviderImpl() { var weather: Weather? var forecastResponse: okhttp3.Response? = null - var sunriseResponse: okhttp3.Response? = null + var sunResponse: okhttp3.Response? = null + var moonResponse: okhttp3.Response? = null var wEx: WeatherException? = null val query = updateLocationQuery(location) @@ -101,71 +106,97 @@ class MetnoWeatherProvider : WeatherProviderImpl() { val forecastRequest = Request.Builder() .cacheRequestIfNeeded(isKeyRequired(), 15, TimeUnit.MINUTES) .url(String.format(FORECAST_QUERY_URL, query)) - .addHeader("Accept-Encoding", "gzip") - .addHeader("User-Agent", String.format("SimpleWeather (thewizrd.dev@gmail.com) %s", version)) - .build() - - val date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ROOT)) - val sunriseRequest = Request.Builder() - .cacheRequestIfNeeded(isKeyRequired(), 30, TimeUnit.MINUTES) - .url(String.format(SUNRISE_QUERY_URL, query, date)) - .addHeader("Accept-Encoding", "gzip") - .addHeader( - "User-Agent", - String.format("SimpleWeather (thewizrd.dev@gmail.com) %s", version) - ) - .build() - - // Connect to webstream - forecastResponse = httpClient.newCall(forecastRequest).await() - checkForErrors(forecastResponse) - - sunriseResponse = httpClient.newCall(sunriseRequest).await() - checkForErrors(sunriseResponse) - - val forecastStream = forecastResponse.getStream() - val sunrisesetStream = sunriseResponse.getStream() - - // Load weather - val foreRoot = - JSONParser.deserializer(forecastStream, Response::class.java) - val astroRoot = JSONParser.deserializer( - sunrisesetStream, - AstroResponse::class.java + .addHeader("Accept-Encoding", "gzip") + .addHeader( + "User-Agent", + String.format("SimpleWeather (thewizrd.dev@gmail.com) %s", version) ) + .build() + + val date = LocalDateTime.now() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ROOT)) + + val sunRequest = Request.Builder() + .cacheRequestIfNeeded(isKeyRequired(), 30, TimeUnit.MINUTES) + .url(String.format(SUN_QUERY_URL, query, date)) + .addHeader("Accept-Encoding", "gzip") + .addHeader( + "User-Agent", + String.format("SimpleWeather (thewizrd.dev@gmail.com) %s", version) + ) + .build() + + val moonRequest = Request.Builder() + .cacheRequestIfNeeded(isKeyRequired(), 30, TimeUnit.MINUTES) + .url(String.format(MOON_QUERY_URL, query, date)) + .addHeader("Accept-Encoding", "gzip") + .addHeader( + "User-Agent", + String.format("SimpleWeather (thewizrd.dev@gmail.com) %s", version) + ) + .build() - // End Stream - forecastStream.closeQuietly() - sunrisesetStream.closeQuietly() - - requireNotNull(foreRoot) - requireNotNull(astroRoot) - - weather = createWeatherData(foreRoot, astroRoot) - } catch (ex: Exception) { - weather = null - if (ex is IOException) { - wEx = WeatherException(ErrorStatus.NETWORKERROR, ex) - } else if (ex is WeatherException) { - wEx = ex - } - Logger.writeLine(Log.ERROR, ex, "MetnoWeatherProvider: error getting weather data") - } finally { - forecastResponse?.closeQuietly() - sunriseResponse?.closeQuietly() - } + // Connect to webstream + forecastResponse = httpClient.newCall(forecastRequest).await() + checkForErrors(forecastResponse) - if (wEx == null && weather.isNullOrInvalid()) { - wEx = WeatherException(ErrorStatus.NOWEATHER) - } else if (weather != null) { - weather.query = query - } + sunResponse = httpClient.newCall(sunRequest).await() + checkForErrors(sunResponse) + + moonResponse = httpClient.newCall(moonRequest).await() + checkForErrors(moonResponse) + + val forecastStream = forecastResponse.getStream() + val sunStream = sunResponse.getStream() + val moonStream = moonResponse.getStream() - if (wEx != null) throw wEx + // Load weather + val foreRoot = + JSONParser.deserializer(forecastStream, Response::class.java) + val sunRoot = JSONParser.deserializer( + sunStream, + SunResponse::class.java + ) + val moonRoot = JSONParser.deserializer( + moonStream, + MoonResponse::class.java + ) + + // End Stream + forecastStream.closeQuietly() + sunStream.closeQuietly() + moonStream.closeQuietly() + + requireNotNull(foreRoot) + requireNotNull(sunRoot) + requireNotNull(moonRoot) + + weather = createWeatherData(foreRoot, sunRoot, moonRoot) + } catch (ex: Exception) { + weather = null + if (ex is IOException) { + wEx = WeatherException(ErrorStatus.NETWORKERROR, ex) + } else if (ex is WeatherException) { + wEx = ex + } + Logger.writeLine(Log.ERROR, ex, "MetnoWeatherProvider: error getting weather data") + } finally { + forecastResponse?.closeQuietly() + sunResponse?.closeQuietly() + moonResponse?.closeQuietly() + } - return@withContext weather!! + if (wEx == null && weather.isNullOrInvalid()) { + wEx = WeatherException(ErrorStatus.NOWEATHER) + } else if (weather != null) { + weather.query = query } + if (wEx != null) throw wEx + + return@withContext weather!! + } + override suspend fun updateWeatherData(location: LocationData, weather: Weather) { // OWM reports datetime in UTC; add location tz_offset val offset = location.tzOffset @@ -197,8 +228,10 @@ class MetnoWeatherProvider : WeatherProviderImpl() { val sunset = weather.astronomy.sunset.toLocalTime() weather.condition.weather = getWeatherCondition(weather.condition.icon) - weather.condition.icon = getWeatherIcon(now.isBefore(sunrise) || now.isAfter(sunset), weather.condition.icon) - weather.condition.observationTime = weather.condition.observationTime.withZoneSameInstant(offset) + weather.condition.icon = + getWeatherIcon(now.isBefore(sunrise) || now.isAfter(sunset), weather.condition.icon) + weather.condition.observationTime = + weather.condition.observationTime.withZoneSameInstant(offset) for (forecast in weather.forecast) { forecast.date = forecast.date.plusSeconds(offset.totalSeconds.toLong()) @@ -222,13 +255,23 @@ class MetnoWeatherProvider : WeatherProviderImpl() { override fun updateLocationQuery(weather: Weather): String { val df = DecimalFormat.getInstance(Locale.ROOT) as DecimalFormat df.applyPattern("0.####") - return String.format(Locale.ROOT, "lat=%s&lon=%s", df.format(weather.location.latitude), df.format(weather.location.longitude)) + return String.format( + Locale.ROOT, + "lat=%s&lon=%s", + df.format(weather.location.latitude), + df.format(weather.location.longitude) + ) } override fun updateLocationQuery(location: LocationData): String { val df = DecimalFormat.getInstance(Locale.ROOT) as DecimalFormat df.applyPattern("0.####") - return String.format(Locale.ROOT, "lat=%s&lon=%s", df.format(location.latitude), df.format(location.longitude)) + return String.format( + Locale.ROOT, + "lat=%s&lon=%s", + df.format(location.latitude), + df.format(location.longitude) + ) } override fun getWeatherIcon(icon: String?): String { @@ -253,6 +296,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.DAY_SUNNY } } + "cloudy" -> weatherIcon = WeatherIcons.CLOUDY "fair", "partlycloudy" -> { weatherIcon = when { @@ -260,6 +304,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.DAY_PARTLY_CLOUDY } } + "fog" -> weatherIcon = WeatherIcons.FOG "heavyrain" -> weatherIcon = WeatherIcons.RAIN_WIND "heavyrainandthunder" -> weatherIcon = WeatherIcons.THUNDERSTORM @@ -270,6 +315,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.RAIN_WIND } } + "heavyrainshowersandthunder", "lightrainshowersandthunder" -> { weatherIcon = when { isDay -> WeatherIcons.DAY_STORM_SHOWERS @@ -277,6 +323,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.STORM_SHOWERS } } + "heavysleet", "lightsleet", "sleet" -> weatherIcon = WeatherIcons.SLEET "heavysleetandthunder", "lightsleetandthunder", "sleetandthunder" -> { weatherIcon = when { @@ -284,6 +331,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.DAY_SLEET_STORM } } + "heavysleetshowersandthunder", "lightssleetshowersandthunder", "sleetshowersandthunder" -> { weatherIcon = when { @@ -292,6 +340,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.SLEET_STORM } } + "heavysleetshowers" -> { weatherIcon = when { isDay -> WeatherIcons.DAY_SLEET @@ -299,6 +348,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.SLEET } } + "heavysnow" -> weatherIcon = WeatherIcons.SNOW_WIND "heavysnowandthunder", "heavysnowshowersandthunder", "lightsnowandthunder", "lightssnowshowersandthunder", "snowandthunder", "snowshowersandthunder" -> { @@ -307,6 +357,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.DAY_SNOW_THUNDERSTORM } } + "heavysnowshowers" -> { weatherIcon = when { isDay -> WeatherIcons.DAY_SNOW_WIND @@ -314,6 +365,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.SNOW_WIND } } + "lightrain" -> weatherIcon = WeatherIcons.SPRINKLE "lightrainandthunder", "rainandthunder" -> weatherIcon = WeatherIcons.STORM_SHOWERS "lightrainshowers", "rainshowers" -> { @@ -323,6 +375,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.SHOWERS } } + "lightsleetshowers", "sleetshowers" -> { weatherIcon = when { isDay -> WeatherIcons.DAY_SLEET @@ -330,6 +383,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.SLEET } } + "lightsnow", "snow" -> weatherIcon = WeatherIcons.SNOW "lightsnowshowers", "snowshowers" -> { weatherIcon = when { @@ -338,6 +392,7 @@ class MetnoWeatherProvider : WeatherProviderImpl() { else -> WeatherIcons.SNOW } } + "rain" -> weatherIcon = WeatherIcons.RAIN "rainshowersandthunder" -> { weatherIcon = when { @@ -364,57 +419,74 @@ class MetnoWeatherProvider : WeatherProviderImpl() { "clearsky" -> { context.getString(R.string.weather_clearsky) } + "cloudy" -> { context.getString(R.string.weather_cloudy) } + "fair" -> { context.getString(R.string.weather_fair) } + "fog" -> { context.getString(R.string.weather_fog) } + "heavyrain" -> { context.getString(R.string.weather_heavyrain) } + "heavyrainandthunder", "heavyrainshowersandthunder", "lightrainandthunder", "lightrainshowersandthunder", "rainandthunder", "rainshowersandthunder" -> { context.getString(R.string.weather_tstorms) } + "heavyrainshowers", "lightrainshowers", "rainshowers" -> { context.getString(R.string.weather_rainshowers) } + "heavysleet", "heavysleetshowers" -> { context.getString(R.string.weather_sleet) } + "heavysleetandthunder", "heavysleetshowersandthunder", "lightsleetandthunder", "lightssleetshowersandthunder", "sleetandthunder", "sleetshowersandthunder" -> { context.getString(R.string.weather_sleet_tstorms) } + "heavysnow", "heavysnowshowers" -> { context.getString(R.string.weather_heavysnow) } + "heavysnowandthunder", "heavysnowshowersandthunder", "lightsnowandthunder", "lightssnowshowersandthunder", "snowandthunder", "snowshowersandthunder" -> { context.getString(R.string.weather_snow_tstorms) } + "lightrain" -> { context.getString(R.string.weather_lightrain) } + "lightsleet", "lightsleetshowers", "sleet", "sleetshowers" -> { context.getString(R.string.weather_sleet) } + "lightsnow", "lightsnowshowers" -> { context.getString(R.string.weather_lightsnowshowers) } + "partlycloudy" -> { context.getString(R.string.weather_partlycloudy) } + "rain" -> { context.getString(R.string.weather_rain) } + "snow", "snowshowers" -> { context.getString(R.string.weather_snow) } + else -> { super.getWeatherCondition(icon) } @@ -443,7 +515,8 @@ class MetnoWeatherProvider : WeatherProviderImpl() { val now = ZonedDateTime.now(tz).toLocalTime() // Determine whether its night using sunset/rise times - if (now.toNanoOfDay() < sunrise.toNanoOfDay() || now.toNanoOfDay() > sunset.toNanoOfDay()) isNight = true + if (now.toNanoOfDay() < sunrise.toNanoOfDay() || now.toNanoOfDay() > sunset.toNanoOfDay()) isNight = + true } return isNight diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/MoonResponse.kt b/weather-api/src/main/java/com/thewizrd/weather_api/metno/MoonResponse.kt new file mode 100644 index 000000000..1a2398ff8 --- /dev/null +++ b/weather-api/src/main/java/com/thewizrd/weather_api/metno/MoonResponse.kt @@ -0,0 +1,94 @@ +package com.thewizrd.weather_api.metno + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class MoonResponse( + + @Json(name = "licenseURL") + val licenseURL: String? = null, + + @Json(name = "copyright") + val copyright: String? = null, + + @Json(name = "geometry") + val geometry: Geometry? = null, + + @Json(name = "type") + val type: String? = null, + + @Json(name = "when") + val _when: When? = null, + + @Json(name = "properties") + val properties: MoonProperties? = null +) + +@JsonClass(generateAdapter = true) +data class Moonset( + + @Json(name = "azimuth") + val azimuth: Float? = null, + + @Json(name = "time") + val time: String? = null +) + +@JsonClass(generateAdapter = true) +data class MoonProperties( + + @Json(name = "moonset") + val moonset: Moonset? = null, + + @Json(name = "moonphase") + val moonphase: Float? = null, + + @Json(name = "moonrise") + val moonrise: Moonrise? = null, + + @Json(name = "body") + val body: String? = null, + + @Json(name = "low_moon") + val lowMoon: LowMoon? = null, + + @Json(name = "high_moon") + val highMoon: HighMoon? = null +) + +@JsonClass(generateAdapter = true) +data class Moonrise( + + @Json(name = "azimuth") + val azimuth: Float? = null, + + @Json(name = "time") + val time: String? = null +) + +@JsonClass(generateAdapter = true) +data class LowMoon( + + @Json(name = "visible") + val visible: Boolean? = null, + + @Json(name = "time") + val time: String? = null, + + @Json(name = "disc_centre_elevation") + val discCentreElevation: Float? = null +) + +@JsonClass(generateAdapter = true) +data class HighMoon( + + @Json(name = "visible") + val visible: Boolean? = null, + + @Json(name = "time") + val time: String? = null, + + @Json(name = "disc_centre_elevation") + val discCentreElevation: Float? = null +) diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonphase.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonphase.java deleted file mode 100644 index 19131d299..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonphase.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Moonphase { - - @Json(name = "time") - private String time; - - @Json(name = "value") - private String value; - - @Json(name = "desc") - private String desc; - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setValue(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonposition.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonposition.java deleted file mode 100644 index 3fcb33c07..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonposition.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Moonposition { - - @Json(name = "phase") - private String phase; - - @Json(name = "elevation") - private String elevation; - - @Json(name = "range") - private String range; - - @Json(name = "azimuth") - private String azimuth; - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setPhase(String phase) { - this.phase = phase; - } - - public String getPhase() { - return phase; - } - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getElevation() { - return elevation; - } - - public void setRange(String range) { - this.range = range; - } - - public String getRange() { - return range; - } - - public void setAzimuth(String azimuth) { - this.azimuth = azimuth; - } - - public String getAzimuth() { - return azimuth; - } - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonrise.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonrise.java deleted file mode 100644 index 59c007e97..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonrise.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Moonrise { - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonset.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonset.java deleted file mode 100644 index e24a08331..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonset.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Moonset { - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonshadow.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonshadow.java deleted file mode 100644 index 26c8dd44d..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Moonshadow.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Moonshadow { - - @Json(name = "elevation") - private String elevation; - - @Json(name = "azimuth") - private String azimuth; - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getElevation() { - return elevation; - } - - public void setAzimuth(String azimuth) { - this.azimuth = azimuth; - } - - public String getAzimuth() { - return azimuth; - } - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarmidnight.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarmidnight.java deleted file mode 100644 index 70a7b7d33..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarmidnight.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Solarmidnight { - - @Json(name = "elevation") - private String elevation; - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getElevation() { - return elevation; - } - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarnoon.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarnoon.java deleted file mode 100644 index 8584f5a70..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Solarnoon.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Solarnoon { - - @Json(name = "elevation") - private String elevation; - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getElevation() { - return elevation; - } - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/SunResponse.kt b/weather-api/src/main/java/com/thewizrd/weather_api/metno/SunResponse.kt new file mode 100644 index 000000000..fea1ab016 --- /dev/null +++ b/weather-api/src/main/java/com/thewizrd/weather_api/metno/SunResponse.kt @@ -0,0 +1,91 @@ +package com.thewizrd.weather_api.metno + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class SunResponse( + + @Json(name = "licenseURL") + val licenseURL: String? = null, + + @Json(name = "copyright") + val copyright: String? = null, + + @Json(name = "geometry") + val geometry: Geometry? = null, + + @Json(name = "type") + val type: String? = null, + + @Json(name = "when") + val _when: When? = null, + + @Json(name = "properties") + val properties: SunProperties? = null +) + +@JsonClass(generateAdapter = true) +data class Solarnoon( + + @Json(name = "visible") + val visible: Boolean? = null, + + @Json(name = "time") + val time: String? = null, + + @Json(name = "disc_centre_elevation") + val discCentreElevation: Float? = null +) + +@JsonClass(generateAdapter = true) +data class Sunrise( + + @Json(name = "azimuth") + val azimuth: Float? = null, + + @Json(name = "time") + val time: String? = null +) + +@JsonClass(generateAdapter = true) +data class Sunset( + + @Json(name = "azimuth") + val azimuth: Float? = null, + + @Json(name = "time") + val time: String? = null +) + +@JsonClass(generateAdapter = true) +data class Solarmidnight( + + @Json(name = "visible") + val visible: Boolean? = null, + + @Json(name = "time") + val time: String? = null, + + @Json(name = "disc_centre_elevation") + val discCentreElevation: Float? = null +) + +@JsonClass(generateAdapter = true) +data class SunProperties( + + @Json(name = "solarnoon") + val solarnoon: Solarnoon? = null, + + @Json(name = "sunrise") + val sunrise: Sunrise? = null, + + @Json(name = "sunset") + val sunset: Sunset? = null, + + @Json(name = "body") + val body: String? = null, + + @Json(name = "solarmidnight") + val solarmidnight: Solarmidnight? = null +) diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunrise.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunrise.java deleted file mode 100644 index e188e6d2b..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunrise.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Sunrise { - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunset.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunset.java deleted file mode 100644 index cee4ca361..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/Sunset.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class Sunset { - - @Json(name = "time") - private String time; - - @Json(name = "desc") - private String desc; - - public void setTime(String time) { - this.time = time; - } - - public String getTime() { - return time; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String getDesc() { - return desc; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/TimeItem.java b/weather-api/src/main/java/com/thewizrd/weather_api/metno/TimeItem.java deleted file mode 100644 index 0f1807b5c..000000000 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/TimeItem.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.thewizrd.weather_api.metno; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonClass; - -@JsonClass(generateAdapter = true, generator = "java") -public class TimeItem { - - @Json(name = "date") - private String date; - - @Json(name = "moonposition") - private Moonposition moonposition; - - @Json(name = "solarnoon") - private Solarnoon solarnoon; - - @Json(name = "sunrise") - private Sunrise sunrise; - - @Json(name = "moonphase") - private Moonphase moonphase; - - @Json(name = "moonshadow") - private Moonshadow moonshadow; - - @Json(name = "sunset") - private Sunset sunset; - - @Json(name = "moonrise") - private Moonrise moonrise; - - @Json(name = "solarmidnight") - private Solarmidnight solarmidnight; - - @Json(name = "low_moon") - private LowMoon lowMoon; - - @Json(name = "high_moon") - private HighMoon highMoon; - - @Json(name = "moonset") - private Moonset moonset; - - public void setDate(String date) { - this.date = date; - } - - public String getDate() { - return date; - } - - public void setMoonposition(Moonposition moonposition) { - this.moonposition = moonposition; - } - - public Moonposition getMoonposition() { - return moonposition; - } - - public void setSolarnoon(Solarnoon solarnoon) { - this.solarnoon = solarnoon; - } - - public Solarnoon getSolarnoon() { - return solarnoon; - } - - public void setSunrise(Sunrise sunrise) { - this.sunrise = sunrise; - } - - public Sunrise getSunrise() { - return sunrise; - } - - public void setMoonphase(Moonphase moonphase) { - this.moonphase = moonphase; - } - - public Moonphase getMoonphase() { - return moonphase; - } - - public void setMoonshadow(Moonshadow moonshadow) { - this.moonshadow = moonshadow; - } - - public Moonshadow getMoonshadow() { - return moonshadow; - } - - public void setSunset(Sunset sunset) { - this.sunset = sunset; - } - - public Sunset getSunset() { - return sunset; - } - - public void setMoonrise(Moonrise moonrise) { - this.moonrise = moonrise; - } - - public Moonrise getMoonrise() { - return moonrise; - } - - public void setSolarmidnight(Solarmidnight solarmidnight) { - this.solarmidnight = solarmidnight; - } - - public Solarmidnight getSolarmidnight() { - return solarmidnight; - } - - public void setLowMoon(LowMoon lowMoon) { - this.lowMoon = lowMoon; - } - - public LowMoon getLowMoon() { - return lowMoon; - } - - public void setHighMoon(HighMoon highMoon) { - this.highMoon = highMoon; - } - - public HighMoon getHighMoon() { - return highMoon; - } - - public Moonset getMoonset() { - return moonset; - } - - public void setMoonset(Moonset moonset) { - this.moonset = moonset; - } -} \ No newline at end of file diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/metno/WeatherData.kt b/weather-api/src/main/java/com/thewizrd/weather_api/metno/WeatherData.kt index 07e8fb27c..a8a96c7f8 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/metno/WeatherData.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/metno/WeatherData.kt @@ -5,9 +5,19 @@ import com.thewizrd.shared_resources.utils.DateTimeUtils import com.thewizrd.shared_resources.utils.getBeaufortScale import com.thewizrd.shared_resources.utils.getFeelsLikeTemp import com.thewizrd.shared_resources.weatherdata.WeatherAPI -import com.thewizrd.shared_resources.weatherdata.model.* +import com.thewizrd.shared_resources.weatherdata.model.Astronomy +import com.thewizrd.shared_resources.weatherdata.model.Atmosphere +import com.thewizrd.shared_resources.weatherdata.model.Beaufort +import com.thewizrd.shared_resources.weatherdata.model.Condition +import com.thewizrd.shared_resources.weatherdata.model.Forecast +import com.thewizrd.shared_resources.weatherdata.model.ForecastExtras +import com.thewizrd.shared_resources.weatherdata.model.HourlyForecast import com.thewizrd.shared_resources.weatherdata.model.Location +import com.thewizrd.shared_resources.weatherdata.model.MoonPhase import com.thewizrd.shared_resources.weatherdata.model.MoonPhase.MoonPhaseType +import com.thewizrd.shared_resources.weatherdata.model.Precipitation +import com.thewizrd.shared_resources.weatherdata.model.UV +import com.thewizrd.shared_resources.weatherdata.model.Weather import java.text.DecimalFormat import java.time.Instant import java.time.LocalDateTime @@ -15,10 +25,10 @@ import java.time.ZoneOffset import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit -import java.util.* +import java.util.Locale import kotlin.math.roundToInt -fun createWeatherData(foreRoot: Response, astroRoot: AstroResponse): Weather { +fun createWeatherData(foreRoot: Response, sunRoot: SunResponse?, moonRoot: MoonResponse?): Weather { return Weather().apply { val now = ZonedDateTime.now(ZoneOffset.UTC) @@ -104,12 +114,19 @@ fun createWeatherData(foreRoot: Response, astroRoot: AstroResponse): Weather { hrForecast.removeAt(hrForecast.size - 1) } - astronomy = createAstronomy(astroRoot) + if (sunRoot != null && moonRoot != null) { + astronomy = createAstronomy(sunRoot, moonRoot) + } ttl = 120 val df = DecimalFormat.getInstance(Locale.ROOT) as DecimalFormat df.applyPattern("#.####") - query = String.format(Locale.ROOT, "lat=%s&lon=%s", df.format(location.latitude), location.longitude) + query = String.format( + Locale.ROOT, + "lat=%s&lon=%s", + df.format(location.latitude), + location.longitude + ) if ((condition.highF == null || condition.highC == null) && forecast.size > 0) { condition.highF = forecast[0].highF @@ -128,8 +145,8 @@ fun createLocation(foreRoot: Response): Location { return Location().apply { // API doesn't provide location name (at all) name = null - latitude = foreRoot.geometry.coordinates[1] - longitude = foreRoot.geometry.coordinates[0] + latitude = foreRoot.geometry?.coordinates?.get(1) + longitude = foreRoot.geometry?.coordinates?.get(0) tzLong = null } } @@ -290,31 +307,45 @@ fun createForecast(time: TimeseriesItem): Forecast { } } -fun createAstronomy(astroRoot: AstroResponse): Astronomy { +fun createAstronomy(sunRoot: SunResponse, moonRoot: MoonResponse): Astronomy { return Astronomy().apply { - var moonPhaseValue = -1 - - for (time in astroRoot.location.time) { - if (time.sunrise != null) { - sunrise = ZonedDateTime.parse(astroRoot.location.time[0].sunrise.time, - DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() - } - if (time.sunset != null) { - sunset = ZonedDateTime.parse(astroRoot.location.time[0].sunset.time, - DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() - } + sunRoot.properties?.sunrise?.time?.let { + sunrise = + ZonedDateTime.parse(it, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() + } + sunRoot.properties?.sunset?.time?.let { + sunset = + ZonedDateTime.parse(it, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() + } + moonRoot.properties?.moonrise?.time?.let { + moonrise = + ZonedDateTime.parse(it, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() + } + moonRoot.properties?.moonset?.time?.let { + moonset = + ZonedDateTime.parse(it, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() + } - if (time.moonrise != null) { - moonrise = ZonedDateTime.parse(astroRoot.location.time[0].moonrise.time, - DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() - } - if (time.moonset != null) { - moonset = ZonedDateTime.parse(astroRoot.location.time[0].moonset.time, - DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime() + moonRoot.properties?.moonphase?.let { moonPhaseValue -> + val moonPhaseType = if (moonPhaseValue >= 0.1f && moonPhaseValue < 89.9f) { + MoonPhaseType.WAXING_CRESCENT + } else if (moonPhaseValue >= 89.9f && moonPhaseValue < 90.1f) { + MoonPhaseType.FIRST_QTR + } else if (moonPhaseValue >= 90.1f && moonPhaseValue < 179.9f) { + MoonPhaseType.WAXING_GIBBOUS + } else if (moonPhaseValue >= 179.9f && moonPhaseValue < 180.1f) { + MoonPhaseType.FULL_MOON + } else if (moonPhaseValue >= 180.1f && moonPhaseValue < 269.9f) { + MoonPhaseType.WANING_GIBBOUS + } else if (moonPhaseValue >= 269.9f && moonPhaseValue < 270.1f) { + MoonPhaseType.LAST_QTR + } else if (moonPhaseValue >= 270.1f && moonPhaseValue < 359.9f) { + MoonPhaseType.WANING_CRESCENT + } else { // 0 + MoonPhaseType.NEWMOON } - if (time.moonphase != null) - moonPhaseValue = time.moonphase.value.toFloat().roundToInt() + moonPhase = MoonPhase(moonPhaseType) } // If the sun won't set/rise, set time to the future @@ -330,25 +361,5 @@ fun createAstronomy(astroRoot: AstroResponse): Astronomy { if (moonset == null) { moonset = DateTimeUtils.LOCALDATETIME_MIN } - - val moonPhaseType = if (moonPhaseValue >= 2 && moonPhaseValue < 23) { - MoonPhaseType.WAXING_CRESCENT - } else if (moonPhaseValue >= 23 && moonPhaseValue < 26) { - MoonPhaseType.FIRST_QTR - } else if (moonPhaseValue >= 26 && moonPhaseValue < 48) { - MoonPhaseType.WAXING_GIBBOUS - } else if (moonPhaseValue >= 48 && moonPhaseValue < 52) { - MoonPhaseType.FULL_MOON - } else if (moonPhaseValue >= 52 && moonPhaseValue < 73) { - MoonPhaseType.WANING_GIBBOUS - } else if (moonPhaseValue >= 73 && moonPhaseValue < 76) { - MoonPhaseType.LAST_QTR - } else if (moonPhaseValue >= 76 && moonPhaseValue < 98) { - MoonPhaseType.WANING_CRESCENT - } else { // 0, 1, 98, 99, 100 - MoonPhaseType.NEWMOON - } - - moonPhase = MoonPhase(moonPhaseType) } } \ No newline at end of file From 68319170d07534cae8c36da61220a27d9017913f Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Thu, 18 Jan 2024 22:05:22 -0500 Subject: [PATCH 3/9] LocationProvider: add fallback if fused location provider is unavailable * For wearables, if the paired phone is not connected or location is off, a location will not likely be returned * Add an escape plan for wearables to use on-device location provider --- .../common/location/LocationProvider.kt | 207 ++++++++++++------ 1 file changed, 142 insertions(+), 65 deletions(-) diff --git a/common/src/fullgms/java/com/thewizrd/common/location/LocationProvider.kt b/common/src/fullgms/java/com/thewizrd/common/location/LocationProvider.kt index d5c2b738a..793a51e21 100644 --- a/common/src/fullgms/java/com/thewizrd/common/location/LocationProvider.kt +++ b/common/src/fullgms/java/com/thewizrd/common/location/LocationProvider.kt @@ -3,16 +3,19 @@ package com.thewizrd.common.location import android.annotation.SuppressLint import android.app.Activity import android.content.Context -import android.location.Criteria import android.location.Location import android.location.LocationManager +import android.os.Build import android.util.Log import androidx.core.location.LocationManagerCompat import androidx.core.os.CancellationSignal import com.google.android.gms.location.FusedLocationProviderClient -import com.google.android.gms.location.LocationRequest import com.google.android.gms.location.LocationServices +import com.google.android.gms.location.Priority import com.google.android.gms.tasks.CancellationTokenSource +import com.google.android.gms.tasks.Task +import com.google.android.gms.tasks.Tasks +import com.google.android.gms.wearable.Wearable import com.thewizrd.common.R import com.thewizrd.common.helpers.locationPermissionEnabled import com.thewizrd.common.utils.ErrorMessage @@ -22,6 +25,7 @@ import com.thewizrd.shared_resources.exceptions.WeatherException import com.thewizrd.shared_resources.locationdata.LocationData import com.thewizrd.shared_resources.locationdata.toLocation import com.thewizrd.shared_resources.locationdata.toLocationData +import com.thewizrd.shared_resources.utils.ContextUtils.isPhone import com.thewizrd.shared_resources.utils.ConversionMethods import com.thewizrd.shared_resources.utils.Logger import com.thewizrd.weather_api.weatherModule @@ -65,16 +69,12 @@ class LocationProvider { suspend fun getLastLocation(): Location? { if (!checkPermissions()) return null - if (isGMSAvailable) { + val isFusedLocationAvailable = canUseFusedLocation().await() + + if (isFusedLocationAvailable) { return mFusedLocationProviderClient.lastLocation.await() } else { - val locCriteria = Criteria().apply { - accuracy = Criteria.ACCURACY_COARSE - isCostAllowed = false - powerRequirement = Criteria.POWER_LOW - } - - val provider = mLocationMgr.getBestProvider(locCriteria, true) ?: return null + val provider = getBestProvider() ?: return null return mLocationMgr.getLastKnownLocation(provider) } } @@ -89,74 +89,75 @@ class LocationProvider { return@suspendCancellableCoroutine } - if (isGMSAvailable) { - val cts = CancellationTokenSource() + canUseFusedLocation() + .continueWith { task -> + if (!continuation.isActive) return@continueWith - continuation.invokeOnCancellation { - cts.cancel() - } + val isFusedLocationAvailable = task.result - mFusedLocationProviderClient.getCurrentLocation( - LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, - cts.token - ).addOnCompleteListener { - if (it.isSuccessful) { - Logger.writeLine(Log.INFO, "$TAG: Location update received...") + if (isFusedLocationAvailable) { + val cts = CancellationTokenSource() - if (continuation.isActive) { - continuation.resume(it.result) - } - } else { - it.exception?.let { ex -> - Logger.writeLine(Log.INFO, ex, "$TAG: Error retrieving location...") + continuation.invokeOnCancellation { + cts.cancel() } - if (continuation.isActive) { - continuation.resume(null) + mFusedLocationProviderClient.getCurrentLocation( + Priority.PRIORITY_BALANCED_POWER_ACCURACY, + cts.token + ).addOnCompleteListener { + if (it.isSuccessful) { + Logger.writeLine(Log.INFO, "$TAG: Location update received...") + + if (continuation.isActive) { + continuation.resume(it.result) + } + } else { + it.exception?.let { ex -> + Logger.writeLine(Log.INFO, ex, "$TAG: Error retrieving location...") + } + + if (continuation.isActive) { + continuation.resume(null) + } + } } - } - } - } else { - val locCriteria = Criteria().apply { - accuracy = Criteria.ACCURACY_COARSE - isCostAllowed = false - powerRequirement = Criteria.POWER_LOW - } - - val cancelSignal = CancellationSignal() + } else { + val cancelSignal = CancellationSignal() - continuation.invokeOnCancellation { - cancelSignal.cancel() - } + continuation.invokeOnCancellation { + cancelSignal.cancel() + } - val provider = mLocationMgr.getBestProvider(locCriteria, true) + val provider = getBestProvider() - if (provider == null) { - if (continuation.isActive) { - continuation.resume(null) - } - return@suspendCancellableCoroutine - } + if (provider == null) { + if (continuation.isActive) { + continuation.resume(null) + } + return@continueWith + } - runCatching { - LocationManagerCompat.getCurrentLocation( - mLocationMgr, - provider, - cancelSignal, - Executors.newSingleThreadExecutor() - ) { - Logger.writeLine(Log.INFO, "$TAG: Location update received...") - if (continuation.isActive) { - continuation.resume(it) + runCatching { + LocationManagerCompat.getCurrentLocation( + mLocationMgr, + provider, + cancelSignal, + Executors.newSingleThreadExecutor() + ) { + Logger.writeLine(Log.INFO, "$TAG: Location update received...") + if (continuation.isActive) { + continuation.resume(it) + } + } + }.onFailure { + Logger.writeLine(Log.INFO, it, "$TAG: Error retrieving location...") + if (continuation.isActive) { + continuation.resume(null) + } } } - }.onFailure { - Logger.writeLine(Log.INFO, it, "$TAG: Error retrieving location...") - if (continuation.isActive) { - continuation.resume(null) - } } - } } suspend fun getLatestLocationData(previousLocation: LocationData? = null): LocationResult { @@ -236,4 +237,80 @@ class LocationProvider { return LocationResult.NotChanged(previousLocation, false) } + + private fun getBestProvider(): String? { + val enabledProviders = mLocationMgr.getProviders(true) + + if (enabledProviders.isNotEmpty()) { + return if (mContext.isPhone() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && enabledProviders.contains( + LocationManager.FUSED_PROVIDER + ) + ) { + LocationManager.FUSED_PROVIDER + } else if (enabledProviders.contains(LocationManager.GPS_PROVIDER)) { + LocationManager.GPS_PROVIDER + } else if (enabledProviders.contains(LocationManager.NETWORK_PROVIDER)) { + LocationManager.NETWORK_PROVIDER + } else if (enabledProviders.contains(LocationManager.PASSIVE_PROVIDER)) { + LocationManager.PASSIVE_PROVIDER + } else { + enabledProviders.first() + } + } + + return null + } + + /** + * On non-wearables: Check if Google Play Services are available. If so, return [com.google.android.gms.location.LocationAvailability.isLocationAvailable] + * + * On wearables: Check if Google Play Services are available. If so, check if any paired phone is available and nearby. + * If so, confirm fused location availability [com.google.android.gms.location.LocationAvailability.isLocationAvailable] + * + * @see [FusedLocationProviderClient.getLocationAvailability] + * @see [com.google.android.gms.wearable.NodeClient.getConnectedNodes] + * @return true if we can use fused location provider + */ + private fun canUseFusedLocation(): Task { + return Tasks.forResult(isGMSAvailable) + .continueWithTask { + val isGMSAvailable = it.result + + if (isGMSAvailable) { + if (!mContext.isPhone()) { + // Wearables: FusedLocationProvider will likely not be of use if phone is not connected nearby + // Verify phone status + Wearable.getNodeClient(mContext) + .connectedNodes + .continueWithTask { nodesTask -> + if (it.isSuccessful) { + val nodes = nodesTask.result + val isNearbyNodes = nodes.any { n -> n.isNearby } + if (isNearbyNodes) { + isFusedLocationAvailable() + } else { + Tasks.forResult(false) + } + } else { + Tasks.forResult(false) + } + } + } else { + isFusedLocationAvailable() + } + } else { + Tasks.forResult(false) + } + } + } + + private fun isFusedLocationAvailable(): Task { + return mFusedLocationProviderClient.locationAvailability.continueWith { avail -> + if (avail.isSuccessful) { + avail.result.isLocationAvailable + } else { + false + } + } + } } \ No newline at end of file From 36cbda5be71b57658594286ff108ca5469aa3321 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Fri, 19 Jan 2024 01:18:46 -0500 Subject: [PATCH 4/9] LocationUtils: approx determine if point is within country bounds * If country code is unavailable, using location coords, check if position is within bounding box --- .../viewmodels/WeatherNowViewModel.kt | 4 +- .../viewmodels/LocationSearchViewModel.kt | 17 +-- .../common/weatherdata/WeatherDataLoader.kt | 8 +- .../remoteconfig/RemoteConfigServiceImpl.kt | 27 +++- .../remoteconfig/RemoteConfigService.kt | 7 +- .../shared_resources/utils/LocationUtils.java | 31 ----- .../shared_resources/utils/LocationUtils.kt | 106 +++++++++++++++ .../weatherdata/WeatherProvider.kt | 4 +- .../remoteconfig/RemoteConfigServiceImpl.kt | 39 +++++- .../viewmodels/WeatherNowViewModel.kt | 4 +- .../here/weather/HEREWeatherProvider.kt | 126 +++++++++--------- .../weather/MeteoFranceProvider.kt | 11 +- .../weather_api/nws/NWSWeatherProvider.kt | 11 +- .../weatherdata/WeatherProviderImpl.kt | 8 +- .../weatherdata/WeatherProviderManager.kt | 8 +- 15 files changed, 279 insertions(+), 132 deletions(-) delete mode 100644 shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.java create mode 100644 shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.kt diff --git a/app/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt b/app/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt index 8269949de..db13a5fa3 100644 --- a/app/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt +++ b/app/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt @@ -231,7 +231,7 @@ class WeatherNowViewModel(app: Application) : AndroidViewModel(app) { when (result) { is WeatherResult.Error -> { viewModelState.update { state -> - if (state.locationData?.countryCode?.let { !wm.isRegionSupported(it) } == true) { + if (state.locationData?.let { !wm.isRegionSupported(it) } == true) { Logger.writeLine( Log.WARN, "Location: %s; countryCode: %s", @@ -290,7 +290,7 @@ class WeatherNowViewModel(app: Application) : AndroidViewModel(app) { val weatherData = result.data.toUiModel() viewModelState.update { state -> - if (state.locationData?.countryCode?.let { !wm.isRegionSupported(it) } == true) { + if (state.locationData?.let { !wm.isRegionSupported(it) } == true) { Logger.writeLine( Log.WARN, "Location: %s; countryCode: %s", diff --git a/common/src/main/java/com/thewizrd/common/viewmodels/LocationSearchViewModel.kt b/common/src/main/java/com/thewizrd/common/viewmodels/LocationSearchViewModel.kt index 6030e7833..d8bbb194f 100644 --- a/common/src/main/java/com/thewizrd/common/viewmodels/LocationSearchViewModel.kt +++ b/common/src/main/java/com/thewizrd/common/viewmodels/LocationSearchViewModel.kt @@ -19,6 +19,7 @@ import com.thewizrd.shared_resources.remoteconfig.remoteConfigService import com.thewizrd.shared_resources.utils.Coordinate import com.thewizrd.shared_resources.utils.JSONParser import com.thewizrd.shared_resources.utils.Logger +import com.thewizrd.shared_resources.weatherdata.model.LocationType import com.thewizrd.weather_api.weatherModule import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -148,10 +149,10 @@ class LocationSearchViewModel(app: Application) : AndroidViewModel(app) { if (!settingsManager.isWeatherLoaded() && !BuildConfig.IS_NONGMS) { // Set default provider based on location - val provider = - remoteConfigService.getDefaultWeatherProvider(locQuery.locationCountry) + val provider = remoteConfigService.getDefaultWeatherProvider(locQuery) settingsManager.setAPI(provider) locQuery.updateWeatherSource(provider) + wm.updateAPI() } if (settingsManager.usePersonalKey() && settingsManager.getAPIKey() @@ -164,11 +165,11 @@ class LocationSearchViewModel(app: Application) : AndroidViewModel(app) { return@launch } - if (!wm.isRegionSupported(locQuery.locationCountry)) { + if (!wm.isRegionSupported(locQuery)) { Logger.writeLine( Log.WARN, "Location: %s; countryCode: %s", - JSONParser.serializer(locQuery.toLocationData()), + JSONParser.serializer(locQuery.toLocationData(LocationType.GPS)), locQuery.locationCountry ) postErrorMessage(R.string.error_message_weather_region_unsupported) @@ -179,7 +180,7 @@ class LocationSearchViewModel(app: Application) : AndroidViewModel(app) { } viewModelState.update { - it.copy(currentLocation = currentLocation) + it.copy(currentLocation = locQuery.toLocationData(LocationType.GPS)) } } @@ -288,13 +289,13 @@ class LocationSearchViewModel(app: Application) : AndroidViewModel(app) { if (!settingsManager.isWeatherLoaded() && !BuildConfig.IS_NONGMS) { // Set default provider based on location - val provider = - remoteConfigService.getDefaultWeatherProvider(queryResult.locationCountry) + val provider = remoteConfigService.getDefaultWeatherProvider(queryResult) settingsManager.setAPI(provider) queryResult.updateWeatherSource(provider) + wm.updateAPI() } - if (!wm.isRegionSupported(queryResult.locationCountry)) { + if (!wm.isRegionSupported(queryResult)) { Logger.writeLine( Log.WARN, "Location: %s; countryCode: %s", diff --git a/common/src/main/java/com/thewizrd/common/weatherdata/WeatherDataLoader.kt b/common/src/main/java/com/thewizrd/common/weatherdata/WeatherDataLoader.kt index a9f17a20d..26dc58c57 100644 --- a/common/src/main/java/com/thewizrd/common/weatherdata/WeatherDataLoader.kt +++ b/common/src/main/java/com/thewizrd/common/weatherdata/WeatherDataLoader.kt @@ -131,7 +131,7 @@ class WeatherDataLoader { coroutineContext.ensureActive() // Is the timezone valid? If not try to fetch a valid zone id - if (!wm.isRegionSupported(location.countryCode) && (location.tzLong == "unknown" || location.tzLong == "UTC")) { + if (!wm.isRegionSupported(location) && (location.tzLong == "unknown" || location.tzLong == "UTC")) { if (location.latitude != 0.0 && location.longitude != 0.0) { val tzId = weatherModule.tzdbService.getTimeZone(location.latitude, location.longitude) @@ -143,12 +143,12 @@ class WeatherDataLoader { } } - if (!wm.isRegionSupported(location.countryCode)) { + if (!wm.isRegionSupported(location)) { // If location data hasn't been updated, try loading weather from the previous provider if (!location.weatherSource.isNullOrBlank()) { val provider = weatherModule.weatherManager.getWeatherProvider(location.weatherSource) - if (provider.isRegionSupported(location.countryCode)) { + if (provider.isRegionSupported(location)) { weather = provider.getWeather(location) } } @@ -267,7 +267,7 @@ class WeatherDataLoader { if (weather != null && weather.source != settingsMgr.getAPI() || location.weatherSource != settingsMgr.getAPI()) { // Only update location data if location region is supported by new API // If not don't update so we can use fallback (previously used API) - if (wm.isRegionSupported(location.countryCode)) { + if (wm.isRegionSupported(location)) { // Update location query and source for new API val oldKey = location.query ?: null diff --git a/shared_resources/src/fullgms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt b/shared_resources/src/fullgms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt index b7c48883a..85b58c190 100644 --- a/shared_resources/src/fullgms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt +++ b/shared_resources/src/fullgms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt @@ -2,6 +2,8 @@ package com.thewizrd.shared_resources.remoteconfig import com.google.firebase.remoteconfig.FirebaseRemoteConfig import com.thewizrd.shared_resources.appLib +import com.thewizrd.shared_resources.locationdata.LocationData +import com.thewizrd.shared_resources.locationdata.LocationQuery import com.thewizrd.shared_resources.utils.JSONParser import com.thewizrd.shared_resources.utils.LocationUtils import com.thewizrd.shared_resources.weatherdata.WeatherAPI @@ -69,14 +71,33 @@ class RemoteConfigServiceImpl : RemoteConfigService { } @WeatherAPI.WeatherProviders - override fun getDefaultWeatherProvider(countryCode: String?): String { + override fun getDefaultWeatherProvider(location: LocationQuery): String { return when { - LocationUtils.isUS(countryCode) -> { + LocationUtils.isUS(location) -> { WeatherAPI.NWS } - LocationUtils.isFrance(countryCode) -> { + + LocationUtils.isFrance(location) -> { + WeatherAPI.METEOFRANCE + } + + else -> { + getDefaultWeatherProvider() + } + } + } + + @WeatherAPI.WeatherProviders + override fun getDefaultWeatherProvider(location: LocationData): String { + return when { + LocationUtils.isUS(location) -> { + WeatherAPI.NWS + } + + LocationUtils.isFrance(location) -> { WeatherAPI.METEOFRANCE } + else -> { getDefaultWeatherProvider() } diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigService.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigService.kt index 2edfa20ea..6b1b6fb54 100644 --- a/shared_resources/src/main/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigService.kt +++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigService.kt @@ -1,5 +1,7 @@ package com.thewizrd.shared_resources.remoteconfig +import com.thewizrd.shared_resources.locationdata.LocationData +import com.thewizrd.shared_resources.locationdata.LocationQuery import com.thewizrd.shared_resources.weatherdata.WeatherAPI val remoteConfigService: RemoteConfigService by lazy { RemoteConfigServiceImpl() } @@ -14,7 +16,10 @@ interface RemoteConfigService { fun getDefaultWeatherProvider(): String @WeatherAPI.WeatherProviders - fun getDefaultWeatherProvider(countryCode: String?): String + fun getDefaultWeatherProvider(location: LocationQuery): String + + @WeatherAPI.WeatherProviders + fun getDefaultWeatherProvider(location: LocationData): String fun checkConfig() suspend fun checkConfigAsync(): Boolean diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.java b/shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.java deleted file mode 100644 index 6be1a81b2..000000000 --- a/shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.thewizrd.shared_resources.utils; - -import androidx.annotation.Nullable; - -import java.util.Locale; - -public class LocationUtils { - public static boolean isUS(@Nullable String countryCode) { - if (StringUtils.isNullOrWhitespace(countryCode)) - return false; - else { - return countryCode.equalsIgnoreCase("us") || countryCode.equalsIgnoreCase("usa") || countryCode.toLowerCase(Locale.ROOT).contains("united states"); - } - } - - public static boolean isUSorCanada(@Nullable String countryCode) { - if (StringUtils.isNullOrWhitespace(countryCode)) - return false; - else { - return isUS(countryCode) || countryCode.equalsIgnoreCase("CA") || countryCode.toLowerCase(Locale.ROOT).contains("canada"); - } - } - - public static boolean isFrance(@Nullable String countryCode) { - if (StringUtils.isNullOrWhitespace(countryCode)) - return false; - else { - return countryCode.equalsIgnoreCase("fr") || countryCode.equalsIgnoreCase("france"); - } - } -} diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.kt new file mode 100644 index 000000000..f0b3d9c5b --- /dev/null +++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/utils/LocationUtils.kt @@ -0,0 +1,106 @@ +@file:Suppress("PropertyName") + +package com.thewizrd.shared_resources.utils + +import com.thewizrd.shared_resources.locationdata.LocationData +import com.thewizrd.shared_resources.locationdata.LocationQuery + +object LocationUtils { + // Source: https://gist.github.com/graydon/11198540 + private val US_BOUNDING_BOX = BoundingBox(24.9493, 49.5904, -125.0011, -66.9326) + private val USCA_BOUNDING_BOX = + BoundingBox(24.4825578966, 71.7611572494, -168.9184947286, -52.2436900411) + private val FR_BOUNDING_BOX = BoundingBox(41.2632185, 51.268318, -5.4534286, 9.8678344) + + fun isUS(countryCode: String?): Boolean { + return if (countryCode.isNullOrBlank()) { + false + } else { + countryCode.equals("us", ignoreCase = true) || countryCode.equals( + "usa", + ignoreCase = true + ) || countryCode.lowercase().contains("united states") + } + } + + fun isUS(location: LocationData): Boolean { + return if (!location.countryCode.isNullOrBlank()) { + isUS(location.countryCode) + } else { + US_BOUNDING_BOX.intersects(location.latitude, location.longitude) + } + } + + fun isUS(location: LocationQuery): Boolean { + return if (!location.locationCountry.isNullOrBlank()) { + isUS(location.locationCountry) + } else { + US_BOUNDING_BOX.intersects(location.locationLat, location.locationLong) + } + } + + fun isUSorCanada(countryCode: String?): Boolean { + return if (countryCode.isNullOrBlank()) { + false + } else { + isUS(countryCode) || countryCode.equals( + "CA", + ignoreCase = true + ) || countryCode.lowercase().contains("canada") + } + } + + fun isUSorCanada(location: LocationData): Boolean { + return if (!location.countryCode.isNullOrBlank()) { + isUSorCanada(location.countryCode) + } else { + USCA_BOUNDING_BOX.intersects(location.latitude, location.longitude) + } + } + + fun isUSorCanada(location: LocationQuery): Boolean { + return if (!location.locationCountry.isNullOrBlank()) { + isUSorCanada(location.locationCountry) + } else { + USCA_BOUNDING_BOX.intersects(location.locationLat, location.locationLong) + } + } + + fun isFrance(countryCode: String?): Boolean { + return if (countryCode.isNullOrBlank()) { + false + } else { + countryCode.equals("fr", ignoreCase = true) || countryCode.equals( + "france", + ignoreCase = true + ) + } + } + + fun isFrance(location: LocationData): Boolean { + return if (!location.countryCode.isNullOrBlank()) { + isFrance(location.countryCode) + } else { + FR_BOUNDING_BOX.intersects(location.latitude, location.longitude) + } + } + + fun isFrance(location: LocationQuery): Boolean { + return if (!location.locationCountry.isNullOrBlank()) { + isFrance(location.locationCountry) + } else { + FR_BOUNDING_BOX.intersects(location.locationLat, location.locationLong) + } + } + + private data class BoundingBox( + val lat_min: Double, + val lat_max: Double, + val lon_min: Double, + val lon_max: Double, + ) { + fun intersects(lat: Double, lon: Double): Boolean { + return (lat in lat_min..lat_max) && (lon in lon_min..lon_max) + } + } +} diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/weatherdata/WeatherProvider.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/weatherdata/WeatherProvider.kt index 220ddf1a8..8afe84773 100644 --- a/shared_resources/src/main/java/com/thewizrd/shared_resources/weatherdata/WeatherProvider.kt +++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/weatherdata/WeatherProvider.kt @@ -22,7 +22,9 @@ interface WeatherProvider { fun needsExternalAlertData(): Boolean - fun isRegionSupported(countryCode: String?): Boolean + fun isRegionSupported(location: LocationData): Boolean + + fun isRegionSupported(location: LocationQuery): Boolean fun getHourlyForecastInterval(): Int diff --git a/shared_resources/src/nongms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt b/shared_resources/src/nongms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt index 0d83469fd..4d52ea64d 100644 --- a/shared_resources/src/nongms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt +++ b/shared_resources/src/nongms/java/com/thewizrd/shared_resources/remoteconfig/RemoteConfigServiceImpl.kt @@ -1,6 +1,8 @@ package com.thewizrd.shared_resources.remoteconfig import android.location.Geocoder +import com.thewizrd.shared_resources.locationdata.LocationData +import com.thewizrd.shared_resources.locationdata.LocationQuery import com.thewizrd.shared_resources.utils.LocationUtils import com.thewizrd.shared_resources.weatherdata.WeatherAPI import com.thewizrd.shared_resources.weatherdata.WeatherAPI.WeatherProviders @@ -28,13 +30,36 @@ class RemoteConfigServiceImpl : RemoteConfigService { } @WeatherProviders - override fun getDefaultWeatherProvider(countryCode: String?): String { - return if (LocationUtils.isUS(countryCode)) { - WeatherAPI.NWS - } else if (LocationUtils.isFrance(countryCode)) { - WeatherAPI.METEOFRANCE - } else { - getDefaultWeatherProvider() + override fun getDefaultWeatherProvider(location: LocationQuery): String { + return when { + LocationUtils.isUS(location) -> { + WeatherAPI.NWS + } + + LocationUtils.isFrance(location) -> { + WeatherAPI.METEOFRANCE + } + + else -> { + getDefaultWeatherProvider() + } + } + } + + @WeatherProviders + override fun getDefaultWeatherProvider(location: LocationData): String { + return when { + LocationUtils.isUS(location) -> { + WeatherAPI.NWS + } + + LocationUtils.isFrance(location) -> { + WeatherAPI.METEOFRANCE + } + + else -> { + getDefaultWeatherProvider() + } } } diff --git a/wearapp/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt b/wearapp/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt index 9befe2237..96b6858cb 100644 --- a/wearapp/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt +++ b/wearapp/src/main/java/com/thewizrd/simpleweather/viewmodels/WeatherNowViewModel.kt @@ -254,7 +254,7 @@ class WeatherNowViewModel(private val app: Application) : AndroidViewModel(app), viewModelState.update { state -> when (result) { is WeatherResult.Error -> { - if (state.locationData?.countryCode?.let { !wm.isRegionSupported(it) } == true) { + if (state.locationData?.let { !wm.isRegionSupported(it) } == true) { Logger.writeLine( Log.WARN, "Location: %s; countryCode: %s", @@ -293,7 +293,7 @@ class WeatherNowViewModel(private val app: Application) : AndroidViewModel(app), ) } is WeatherResult.WeatherWithError -> { - if (state.locationData?.countryCode?.let { !wm.isRegionSupported(it) } == true) { + if (state.locationData?.let { !wm.isRegionSupported(it) } == true) { Logger.writeLine( Log.WARN, "Location: %s; countryCode: %s", diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt index 9845f16ea..73d279c26 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt @@ -106,86 +106,87 @@ class HEREWeatherProvider : WeatherProviderImpl(), WeatherAlertProvider { var response: Response? = null var wEx: WeatherException? = null - try { - // If were under rate limit, deny request - checkRateLimit() + try { + // If were under rate limit, deny request + checkRateLimit() - val authorization = hereOAuthService.getBearerToken(false) + val authorization = hereOAuthService.getBearerToken(false) - if (authorization.isNullOrBlank()) { - throw WeatherException(ErrorStatus.NETWORKERROR).apply { - initCause(Exception("Invalid bearer token: $authorization")) - } + if (authorization.isNullOrBlank()) { + throw WeatherException(ErrorStatus.NETWORKERROR).apply { + initCause(Exception("Invalid bearer token: $authorization")) } + } - val url = if (LocationUtils.isUSorCanada(location.countryCode)) { - String.format(WEATHER_US_CA_QUERY_URL, query, locale) - } else { - String.format(WEATHER_GLOBAL_QUERY_URL, query, locale) - } + val url = if (LocationUtils.isUSorCanada(location)) { + String.format(WEATHER_US_CA_QUERY_URL, query, locale) + } else { + String.format(WEATHER_GLOBAL_QUERY_URL, query, locale) + } - val request = Request.Builder() - .cacheRequestIfNeeded(isKeyRequired(), 1, TimeUnit.HOURS) - .url(url) - .addHeader("Authorization", authorization) - .build() + val request = Request.Builder() + .cacheRequestIfNeeded(isKeyRequired(), 1, TimeUnit.HOURS) + .url(url) + .addHeader("Authorization", authorization) + .build() - // Connect to webstream - response = client.newCall(request).await() - checkForErrors(response) + // Connect to webstream + response = client.newCall(request).await() + checkForErrors(response) - val stream = response.getStream() + val stream = response.getStream() - // Load weather - val root: Rootobject? = JSONParser.deserializer(stream, Rootobject::class.java) + // Load weather + val root: Rootobject? = JSONParser.deserializer(stream, Rootobject::class.java) - // Check for errors - when (root?.type) { - "Invalid Request" -> throw WeatherException( - ErrorStatus.QUERYNOTFOUND, - response.createThrowable() - ) - "Unauthorized" -> throw WeatherException(ErrorStatus.INVALIDAPIKEY) - } + // Check for errors + when (root?.type) { + "Invalid Request" -> throw WeatherException( + ErrorStatus.QUERYNOTFOUND, + response.createThrowable() + ) - // End Stream - stream.closeQuietly() + "Unauthorized" -> throw WeatherException(ErrorStatus.INVALIDAPIKEY) + } - requireNotNull(root) + // End Stream + stream.closeQuietly() - weather = createWeatherData(root) + requireNotNull(root) - // Add weather alerts if available - weather.weatherAlerts = createWeatherAlerts( - root, - weather.location.latitude, weather.location.longitude - ) - } catch (ex: Exception) { - weather = null - if (ex is IOException) { - wEx = WeatherException(ErrorStatus.NETWORKERROR, ex) - } else if (ex is WeatherException) { - wEx = ex - } - Logger.writeLine(Log.ERROR, ex, "HEREWeatherProvider: error getting weather data") - } finally { - response?.close() - } + weather = createWeatherData(root) - if (wEx == null && weather.isNullOrInvalid()) { - wEx = WeatherException(ErrorStatus.NOWEATHER) - } else if (weather != null) { - if (supportsWeatherLocale()) - weather.locale = locale - - weather.query = query + // Add weather alerts if available + weather.weatherAlerts = createWeatherAlerts( + root, + weather.location.latitude, weather.location.longitude + ) + } catch (ex: Exception) { + weather = null + if (ex is IOException) { + wEx = WeatherException(ErrorStatus.NETWORKERROR, ex) + } else if (ex is WeatherException) { + wEx = ex } + Logger.writeLine(Log.ERROR, ex, "HEREWeatherProvider: error getting weather data") + } finally { + response?.close() + } - if (wEx != null) throw wEx + if (wEx == null && weather.isNullOrInvalid()) { + wEx = WeatherException(ErrorStatus.NOWEATHER) + } else if (weather != null) { + if (supportsWeatherLocale()) + weather.locale = locale - return@withContext weather!! + weather.query = query } + if (wEx != null) throw wEx + + return@withContext weather!! + } + @Throws(WeatherException::class) override suspend fun updateWeatherData(location: LocationData, weather: Weather) { val offset = location.tzOffset @@ -250,8 +251,7 @@ class HEREWeatherProvider : WeatherProviderImpl(), WeatherAlertProvider { } } - val country_code = location.countryCode - val url = if (LocationUtils.isUSorCanada(country_code)) { + val url = if (LocationUtils.isUSorCanada(location)) { String.format(ALERT_US_CA_QUERY_URL, location.query, locale) } else { String.format(ALERT_GLOBAL_QUERY_URL, location.query, locale) diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/meteofrance/weather/MeteoFranceProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/meteofrance/weather/MeteoFranceProvider.kt index cd56d8aa8..97295ea91 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/meteofrance/weather/MeteoFranceProvider.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/meteofrance/weather/MeteoFranceProvider.kt @@ -6,6 +6,7 @@ import com.thewizrd.shared_resources.exceptions.ErrorStatus import com.thewizrd.shared_resources.exceptions.WeatherException import com.thewizrd.shared_resources.icons.WeatherIcons import com.thewizrd.shared_resources.locationdata.LocationData +import com.thewizrd.shared_resources.locationdata.LocationQuery import com.thewizrd.shared_resources.okhttp3.OkHttp3Utils.await import com.thewizrd.shared_resources.okhttp3.OkHttp3Utils.getStream import com.thewizrd.shared_resources.remoteconfig.remoteConfigService @@ -80,8 +81,12 @@ class MeteoFranceProvider : WeatherProviderImpl() { return false } - override fun isRegionSupported(countryCode: String?): Boolean { - return LocationUtils.isFrance(countryCode) + override fun isRegionSupported(location: LocationData): Boolean { + return LocationUtils.isFrance(location) + } + + override fun isRegionSupported(location: LocationQuery): Boolean { + return LocationUtils.isFrance(location) } override fun getHourlyForecastInterval(): Int { @@ -110,7 +115,7 @@ class MeteoFranceProvider : WeatherProviderImpl() { var weather: Weather? // MeteoFrance only supports locations in France - if (!LocationUtils.isFrance(location.countryCode)) { + if (!LocationUtils.isFrance(location)) { throw WeatherException(ErrorStatus.QUERYNOTFOUND).apply { initCause(Exception("Unsupported country code: provider (${getWeatherAPI()}), country (${location.countryCode})")) } diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/nws/NWSWeatherProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/nws/NWSWeatherProvider.kt index 60ac25181..c93f95904 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/nws/NWSWeatherProvider.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/nws/NWSWeatherProvider.kt @@ -7,6 +7,7 @@ import com.thewizrd.shared_resources.exceptions.ErrorStatus import com.thewizrd.shared_resources.exceptions.WeatherException import com.thewizrd.shared_resources.icons.WeatherIcons import com.thewizrd.shared_resources.locationdata.LocationData +import com.thewizrd.shared_resources.locationdata.LocationQuery import com.thewizrd.shared_resources.okhttp3.OkHttp3Utils.await import com.thewizrd.shared_resources.okhttp3.OkHttp3Utils.getStream import com.thewizrd.shared_resources.remoteconfig.remoteConfigService @@ -77,8 +78,12 @@ class NWSWeatherProvider : WeatherProviderImpl() { return false } - override fun isRegionSupported(countryCode: String?): Boolean { - return LocationUtils.isUS(countryCode) + override fun isRegionSupported(location: LocationData): Boolean { + return LocationUtils.isUS(location) + } + + override fun isRegionSupported(location: LocationQuery): Boolean { + return LocationUtils.isUS(location) } override fun isKeyRequired(): Boolean { @@ -99,7 +104,7 @@ class NWSWeatherProvider : WeatherProviderImpl() { var weather: Weather? // NWS only supports locations in U.S. - if (!LocationUtils.isUS(location.countryCode)) { + if (!LocationUtils.isUS(location)) { throw WeatherException(ErrorStatus.QUERYNOTFOUND).apply { initCause(Exception("Unsupported country code: provider (${getWeatherAPI()}), country (${location.countryCode})")) } diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderImpl.kt b/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderImpl.kt index 2cba53e3a..705af4311 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderImpl.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderImpl.kt @@ -58,7 +58,11 @@ abstract class WeatherProviderImpl : WeatherProvider, RateLimitedRequest { return true } - override fun isRegionSupported(countryCode: String?): Boolean { + override fun isRegionSupported(location: LocationData): Boolean { + return true + } + + override fun isRegionSupported(location: LocationQuery): Boolean { return true } @@ -277,7 +281,7 @@ abstract class WeatherProviderImpl : WeatherProvider, RateLimitedRequest { * @return A collection of weather alerts currently available */ override suspend fun getAlerts(location: LocationData): Collection? { - return if (LocationUtils.isUS(location.countryCode)) { + return if (LocationUtils.isUS(location)) { NWSAlertProvider().getAlerts(location) } else { //WeatherApiProvider().getAlerts(location) diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderManager.kt b/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderManager.kt index 2aaaa0d1e..7e41d1d5c 100644 --- a/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderManager.kt +++ b/weather-api/src/main/java/com/thewizrd/weather_api/weatherdata/WeatherProviderManager.kt @@ -73,8 +73,12 @@ class WeatherProviderManager internal constructor() : WeatherProvider { return _weatherProvider!!.needsExternalAlertData() } - override fun isRegionSupported(countryCode: String?): Boolean { - return _weatherProvider!!.isRegionSupported(countryCode) + override fun isRegionSupported(location: LocationData): Boolean { + return _weatherProvider!!.isRegionSupported(location) + } + + override fun isRegionSupported(location: LocationQuery): Boolean { + return _weatherProvider!!.isRegionSupported(location) } override fun getHourlyForecastInterval(): Int { From e219b921f20e6bbe93a33b0edd602eae187aff27 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Fri, 19 Jan 2024 01:20:48 -0500 Subject: [PATCH 5/9] SimpleWeather: v5.8.4-build0 --- app/build.gradle | 4 ++-- wearapp/build.gradle | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index cc48032e4..8d593a837 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion // NOTE: Version Code Format (TargetSDK, Version Name, Build Number, Variant Code (Android: 00, WearOS: 01) - versionCode 335830000 - versionName "5.8.3" + versionCode 335840000 + versionName "5.8.4" vectorDrawables.useSupportLibrary true } diff --git a/wearapp/build.gradle b/wearapp/build.gradle index 6fc88209e..bbe702598 100644 --- a/wearapp/build.gradle +++ b/wearapp/build.gradle @@ -17,8 +17,8 @@ android { minSdkVersion 26 targetSdkVersion rootProject.targetSdkVersion // NOTE: Version Code Format (TargetSDK, Version Name, Build Number, Variant Code (Android: 00, WearOS: 01) - versionCode 335830001 - versionName "5.8.3" + versionCode 335840001 + versionName "5.8.4" vectorDrawables.useSupportLibrary true } From da10a4d0a636a395a7ad48213f9a78eba95844e5 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Sat, 20 Jan 2024 21:17:35 -0500 Subject: [PATCH 6/9] wear: update splash screen --- build.gradle | 2 +- .../com/thewizrd/simpleweather/LaunchActivity.kt | 3 +-- wearapp/src/main/res/values-v31/styles.xml | 12 ------------ wearapp/src/main/res/values/styles.xml | 8 ++++---- 4 files changed, 6 insertions(+), 19 deletions(-) delete mode 100644 wearapp/src/main/res/values-v31/styles.xml diff --git a/build.gradle b/build.gradle index 47757b579..67aa1dd2b 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ buildscript { preference_version = '1.2.1' recyclerview_version = '1.3.1' room_version = '2.5.2' - coresplash_version = '1.0.0' + coresplash_version = '1.0.1' work_version = '2.8.1' test_core_version = '1.5.0' diff --git a/wearapp/src/main/java/com/thewizrd/simpleweather/LaunchActivity.kt b/wearapp/src/main/java/com/thewizrd/simpleweather/LaunchActivity.kt index 09acbbf4a..acf2dc77c 100644 --- a/wearapp/src/main/java/com/thewizrd/simpleweather/LaunchActivity.kt +++ b/wearapp/src/main/java/com/thewizrd/simpleweather/LaunchActivity.kt @@ -29,10 +29,9 @@ class LaunchActivity : ComponentActivity() { private var isReadyToView = false override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() super.onCreate(savedInstanceState) - val splashScreen = installSplashScreen() - // Stop activity from rendering until next activity or if immediate update available val content = findViewById(android.R.id.content) content.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener { diff --git a/wearapp/src/main/res/values-v31/styles.xml b/wearapp/src/main/res/values-v31/styles.xml deleted file mode 100644 index c9471861a..000000000 --- a/wearapp/src/main/res/values-v31/styles.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/wearapp/src/main/res/values/styles.xml b/wearapp/src/main/res/values/styles.xml index 1a471d531..24011fcd0 100644 --- a/wearapp/src/main/res/values/styles.xml +++ b/wearapp/src/main/res/values/styles.xml @@ -24,11 +24,11 @@ @style/Widget.Wear.WearChipButton -