Skip to content

Commit 5927ffe

Browse files
authored
Merge pull request #17 from SimpleAppProjects/develop
SimpleWeather: v5.10.3
2 parents 335e313 + a34a264 commit 5927ffe

File tree

40 files changed

+881
-275
lines changed

40 files changed

+881
-275
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ android {
1515
minSdkVersion rootProject.minSdkVersion
1616
targetSdkVersion rootProject.targetSdkVersion
1717
// NOTE: Version Code Format (TargetSDK, Version Name, Build Number, Variant Code (Android: 0, WearOS: 1)
18-
versionCode 345100070
19-
versionName "5.10.1"
18+
versionCode 345100100
19+
versionName "5.10.3"
2020

2121
vectorDrawables {
2222
useSupportLibrary true

app/src/androidTestFullgms/java/com/thewizrd/simpleweather/test/UnitTests.kt

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.thewizrd.shared_resources.utils.Coordinate
2424
import com.thewizrd.shared_resources.utils.DateTimeUtils
2525
import com.thewizrd.shared_resources.utils.JSONParser
2626
import com.thewizrd.shared_resources.utils.LocaleUtils
27+
import com.thewizrd.shared_resources.utils.StringUtils.isNullOrWhitespace
2728
import com.thewizrd.shared_resources.utils.ZoneIdCompat
2829
import com.thewizrd.shared_resources.weatherdata.WeatherAPI
2930
import com.thewizrd.shared_resources.weatherdata.WeatherProvider
@@ -33,11 +34,12 @@ import com.thewizrd.simpleweather.images.ImageDatabase
3334
import com.thewizrd.simpleweather.images.model.ImageData
3435
import com.thewizrd.simpleweather.updates.UpdateInfo
3536
import com.thewizrd.weather_api.aqicn.AQICNProvider
37+
import com.thewizrd.weather_api.google.location.AndroidLocationProvider
3638
import com.thewizrd.weather_api.google.location.GoogleLocationProvider
37-
import com.thewizrd.weather_api.google.location.createLocationModel
3839
import com.thewizrd.weather_api.google.location.getFromLocationNameAsync
3940
import com.thewizrd.weather_api.google.location.isGeocoderAvailable
4041
import com.thewizrd.weather_api.here.auth.hereOAuthService
42+
import com.thewizrd.weather_api.locationiq.LocationIQProvider
4143
import com.thewizrd.weather_api.nws.SolCalcAstroProvider
4244
import com.thewizrd.weather_api.nws.alerts.NWSAlertProvider
4345
import com.thewizrd.weather_api.smc.SunMoonCalcProvider
@@ -348,16 +350,12 @@ class UnitTests {
348350
fun androidGeocoderTest() {
349351
runBlocking(Dispatchers.Default) {
350352
assertTrue(isGeocoderAvailable())
351-
val geocoder = Geocoder(context, Locale.getDefault())
352-
val addressList = withContext(Dispatchers.IO) {
353-
//geocoder.getFromLocation(47.6721646, -122.1706614, 1); // Washington
354-
geocoder.getFromLocation(51.5073884, -0.1334347, 1) // London
353+
val locationProvider = AndroidLocationProvider()
354+
val location = withContext(Dispatchers.IO) {
355+
locationProvider.getLocation(Coordinate(51.5073884, -0.1334347), WeatherAPI.ANDROID)
355356
}
356-
assertFalse(addressList.isNullOrEmpty())
357-
val result = addressList!![0]
358-
assertNotNull(result)
359-
val locQVM = createLocationModel(result, WeatherAPI.ANDROID)
360-
assertFalse(locQVM.locationName.toString().contains("null"))
357+
assertNotNull(location)
358+
assertFalse(location.locationName.toString().contains("null"))
361359
}
362360
}
363361

@@ -381,7 +379,7 @@ class UnitTests {
381379
Coordinate(
382380
queryVM!!.locationLat,
383381
queryVM.locationLong
384-
), WeatherAPI.OPENWEATHERMAP
382+
), WeatherAPI.GOOGLE
385383
)
386384
} else if (locationProvider.needsLocationFromID()) {
387385
locationProvider.getLocationFromID(queryVM!!)
@@ -390,18 +388,57 @@ class UnitTests {
390388
}
391389

392390
assertNotNull(locModel)
391+
assertFalse(locModel?.locationName.isNullOrWhitespace())
392+
assertTrue(locModel?.toLocationData()?.isValid == true)
393+
}
394+
}
395+
396+
@Test
397+
@Throws(WeatherException::class)
398+
fun locIQLocationTest() {
399+
runBlocking(Dispatchers.Default) {
400+
val locationProvider: WeatherLocationProvider = LocationIQProvider()
401+
val locations = withContext(Dispatchers.IO) {
402+
locationProvider.getLocations("Redmond, WA", WeatherAPI.LOCATIONIQ)
403+
}
404+
assertFalse(locations.isEmpty())
405+
406+
val queryVM = locations.find { it.locationName?.startsWith("Redmond") == true }
407+
assertNotNull(queryVM)
393408

394-
if (locModel!!.locationTZLong.isNullOrBlank() && locModel.locationLat != 0.0 && locModel.locationLong != 0.0) {
395-
val tzId = weatherModule.tzdbService.getTimeZone(
396-
locModel.locationLat,
397-
locModel.locationLong
409+
val locModel = if (locationProvider.needsLocationFromName()) {
410+
locationProvider.getLocationFromName(queryVM!!)
411+
} else if (locationProvider.needsLocationFromGeocoder()) {
412+
locationProvider.getLocation(
413+
Coordinate(
414+
queryVM!!.locationLat,
415+
queryVM.locationLong
416+
), WeatherAPI.LOCATIONIQ
398417
)
399-
if ("unknown" != tzId)
400-
locModel.locationTZLong = tzId
418+
} else if (locationProvider.needsLocationFromID()) {
419+
locationProvider.getLocationFromID(queryVM!!)
420+
} else {
421+
queryVM
422+
}
423+
424+
assertNotNull(locModel)
425+
assertFalse(locModel?.locationName.isNullOrWhitespace())
426+
assertTrue(locModel?.toLocationData()?.isValid == true)
427+
}
428+
}
429+
430+
@Test
431+
@Throws(WeatherException::class)
432+
fun locIQLocationGeocoderTest() {
433+
runBlocking(Dispatchers.Default) {
434+
val locationProvider: WeatherLocationProvider = LocationIQProvider()
435+
val locModel = withContext(Dispatchers.IO) {
436+
locationProvider.getLocation(Coordinate(51.5073884, -0.1334347), WeatherAPI.ANDROID)
401437
}
402438

403-
assertFalse(locModel.locationTZLong.isNullOrEmpty())
404-
assertTrue(locModel.toLocationData().isValid)
439+
assertNotNull(locModel)
440+
assertFalse(locModel?.locationName.isNullOrWhitespace())
441+
assertTrue(locModel?.toLocationData()?.isValid == true)
405442
}
406443
}
407444

@@ -425,7 +462,7 @@ class UnitTests {
425462
Coordinate(
426463
queryVM!!.locationLat,
427464
queryVM.locationLong
428-
), WeatherAPI.OPENWEATHERMAP
465+
), WeatherAPI.WEATHERAPI
429466
)
430467
} else if (locationProvider.needsLocationFromID()) {
431468
locationProvider.getLocationFromID(queryVM!!)
@@ -434,18 +471,8 @@ class UnitTests {
434471
}
435472

436473
assertNotNull(locModel)
437-
438-
if (locModel!!.locationTZLong.isNullOrBlank() && locModel.locationLat != 0.0 && locModel.locationLong != 0.0) {
439-
val tzId = weatherModule.tzdbService.getTimeZone(
440-
locModel.locationLat,
441-
locModel.locationLong
442-
)
443-
if ("unknown" != tzId)
444-
locModel.locationTZLong = tzId
445-
}
446-
447-
assertFalse(locModel.locationTZLong.isNullOrEmpty())
448-
assertTrue(locModel.toLocationData().isValid)
474+
assertFalse(locModel?.locationName.isNullOrWhitespace())
475+
assertTrue(locModel?.toLocationData()?.isValid == true)
449476
}
450477
}
451478

app/src/main/java/com/thewizrd/simpleweather/widgets/preferences/AbstractWeatherWidgetPreferenceFragment.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ import com.thewizrd.shared_resources.utils.ContextUtils.isSmallestWidth
5656
import com.thewizrd.shared_resources.utils.Logger
5757
import com.thewizrd.shared_resources.weatherdata.model.AirQuality
5858
import com.thewizrd.shared_resources.weatherdata.model.Atmosphere
59+
import com.thewizrd.shared_resources.weatherdata.model.Beaufort
5960
import com.thewizrd.shared_resources.weatherdata.model.Condition
6061
import com.thewizrd.shared_resources.weatherdata.model.Forecast
6162
import com.thewizrd.shared_resources.weatherdata.model.ForecastExtras
6263
import com.thewizrd.shared_resources.weatherdata.model.HourlyForecast
6364
import com.thewizrd.shared_resources.weatherdata.model.Location
6465
import com.thewizrd.shared_resources.weatherdata.model.LocationType
6566
import com.thewizrd.shared_resources.weatherdata.model.MinutelyForecast
67+
import com.thewizrd.shared_resources.weatherdata.model.Pollen
6668
import com.thewizrd.shared_resources.weatherdata.model.Precipitation
69+
import com.thewizrd.shared_resources.weatherdata.model.UV
6770
import com.thewizrd.shared_resources.weatherdata.model.Weather
6871
import com.thewizrd.simpleweather.R
6972
import com.thewizrd.simpleweather.activities.LocationSearch
@@ -596,15 +599,27 @@ abstract class AbstractWeatherWidgetPreferenceFragment : ToolbarPreferenceFragme
596599
weather = getString(R.string.weather_sunny)
597600
tempF = 70f
598601
tempC = 21f
602+
windDegrees = 292
599603
windMph = 5f
600604
windKph = 8f
605+
windGustMph = 15f
606+
windGustKph = 25f
607+
feelslikeF = 75f
608+
feelslikeC = 23f
601609
highF = 75f
602610
highC = 23f
603611
lowF = 60f
604612
lowC = 15f
605613
icon = WeatherIcons.DAY_SUNNY
606614
airQuality = AirQuality().apply {
607-
index = 46
615+
index = Random.nextInt(0, 301)
616+
}
617+
beaufort = Beaufort(Beaufort.BeaufortScale.valueOf(Random.nextInt(0, 12)))
618+
uv = UV(Random.nextInt(0, 11).toFloat())
619+
pollen = Pollen().apply {
620+
treePollenCount = Pollen.PollenCount.VERY_HIGH
621+
grassPollenCount = Pollen.PollenCount.LOW
622+
ragweedPollenCount = Pollen.PollenCount.MODERATE
608623
}
609624
}
610625
atmosphere = Atmosphere()

app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2Creator.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import android.text.style.TextAppearanceSpan
1010
import android.util.TypedValue
1111
import android.view.View
1212
import android.widget.RemoteViews
13+
import com.thewizrd.common.controls.WeatherDetailsType
1314
import com.thewizrd.common.controls.WeatherUiModel
1415
import com.thewizrd.common.helpers.ColorsUtils
1516
import com.thewizrd.common.utils.ImageUtils
@@ -153,6 +154,10 @@ class WeatherWidget4x2Creator(context: Context, loadBackground: Boolean = true)
153154
R.id.condition_weather,
154155
textColor
155156
)
157+
updateViews.setTextColor(
158+
R.id.condition_feelslike,
159+
textColor
160+
)
156161

157162
updateViews.setTextColor(R.id.date_panel, textColor)
158163
updateViews.setTextColor(R.id.clock_panel, textColor)
@@ -170,6 +175,15 @@ class WeatherWidget4x2Creator(context: Context, loadBackground: Boolean = true)
170175
weather.curTemp?.applySpan(textAppearanceSpan)
171176
)
172177

178+
weather.weatherDetailsMap[WeatherDetailsType.FEELSLIKE]?.let {
179+
updateViews.setTextViewText(
180+
R.id.condition_feelslike,
181+
"${it.label}: ${it.value}".applySpan(textAppearanceSpan)
182+
)
183+
} ?: run {
184+
updateViews.setViewVisibility(R.id.condition_feelslike, View.GONE)
185+
}
186+
173187
buildDate(location, updateViews, appWidgetId, newOptions)
174188
// Open default clock/calendar app
175189
updateViews.setOnClickPendingIntent(
@@ -361,6 +375,11 @@ class WeatherWidget4x2Creator(context: Context, loadBackground: Boolean = true)
361375
TypedValue.COMPLEX_UNIT_SP,
362376
12f * txtSizeMultiplier
363377
)
378+
updateViews.setTextViewTextSize(
379+
R.id.condition_feelslike,
380+
TypedValue.COMPLEX_UNIT_SP,
381+
12f * txtSizeMultiplier
382+
)
364383
}
365384

366385
private fun updateClockSize(views: RemoteViews, appWidgetId: Int, newOptions: Bundle) {

app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2TomorrowCreator.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ class WeatherWidget4x2TomorrowCreator(context: Context, loadBackground: Boolean
172172
R.id.condition_weather,
173173
textColor
174174
)
175+
updateViews.setTextColor(
176+
R.id.condition_feelslike,
177+
textColor
178+
)
175179

176180
updateViews.setTextColor(R.id.date_panel, textColor)
177181
updateViews.setTextColor(R.id.clock_panel, textColor)
@@ -189,6 +193,15 @@ class WeatherWidget4x2TomorrowCreator(context: Context, loadBackground: Boolean
189193
weather.curTemp?.applySpan(textAppearanceSpan)
190194
)
191195

196+
weather.weatherDetailsMap[WeatherDetailsType.FEELSLIKE]?.let {
197+
updateViews.setTextViewText(
198+
R.id.condition_feelslike,
199+
"${it.label}: ${it.value}".applySpan(textAppearanceSpan)
200+
)
201+
} ?: run {
202+
updateViews.setViewVisibility(R.id.condition_feelslike, View.GONE)
203+
}
204+
192205
buildDate(location, updateViews, appWidgetId, newOptions)
193206
// Open default clock/calendar app
194207
updateViews.setOnClickPendingIntent(
@@ -659,6 +672,11 @@ class WeatherWidget4x2TomorrowCreator(context: Context, loadBackground: Boolean
659672
TypedValue.COMPLEX_UNIT_SP,
660673
12f * txtSizeMultiplier
661674
)
675+
updateViews.setTextViewTextSize(
676+
R.id.condition_feelslike,
677+
TypedValue.COMPLEX_UNIT_SP,
678+
12f * txtSizeMultiplier
679+
)
662680
}
663681

664682
private fun updateClockSize(views: RemoteViews, appWidgetId: Int, newOptions: Bundle) {

app/src/main/res/layout/app_widget_4x2.xml

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@
114114

115115
<LinearLayout
116116
android:layout_width="match_parent"
117-
android:layout_height="wrap_content"
117+
android:layout_height="0dp"
118+
android:layout_weight="1"
118119
android:baselineAligned="false"
119120
android:orientation="horizontal">
120121

@@ -156,41 +157,61 @@
156157

157158
</LinearLayout>
158159

159-
<RelativeLayout
160+
<LinearLayout
160161
android:layout_width="wrap_content"
161-
android:layout_height="wrap_content"
162-
android:layout_gravity="center_vertical">
162+
android:layout_height="match_parent"
163+
android:layout_gravity="center_vertical"
164+
android:gravity="center_vertical"
165+
android:orientation="vertical">
163166

164-
<ImageView
165-
android:id="@+id/weather_icon"
167+
<LinearLayout
166168
android:layout_width="wrap_content"
167169
android:layout_height="wrap_content"
168-
android:layout_alignParentStart="true"
169-
android:layout_centerVertical="true"
170170
android:layout_gravity="center_vertical"
171-
android:adjustViewBounds="true"
172-
android:gravity="center_vertical"
173-
android:maxWidth="60dp"
174-
android:maxHeight="60dp"
175-
android:scaleType="fitCenter"
176-
tools:src="@drawable/wi_thunderstorm" />
171+
android:orientation="horizontal"
172+
android:paddingVertical="2dp">
173+
174+
<ImageView
175+
android:id="@+id/weather_icon"
176+
android:layout_width="wrap_content"
177+
android:layout_height="wrap_content"
178+
android:layout_gravity="center_vertical"
179+
android:adjustViewBounds="true"
180+
android:gravity="center_vertical"
181+
android:maxWidth="60dp"
182+
android:maxHeight="60dp"
183+
android:scaleType="fitCenter"
184+
tools:src="@drawable/wi_thunderstorm" />
185+
186+
<TextView
187+
android:id="@+id/condition_temp"
188+
android:layout_width="wrap_content"
189+
android:layout_height="wrap_content"
190+
android:layout_gravity="center_vertical|start"
191+
android:layout_marginStart="2dp"
192+
android:gravity="center_vertical"
193+
android:shadowColor="#000000"
194+
android:textColor="@android:color/white"
195+
android:textSize="28sp"
196+
tools:text="70°F" />
197+
198+
</LinearLayout>
177199

178200
<TextView
179-
android:id="@+id/condition_temp"
180-
android:layout_width="wrap_content"
201+
android:id="@+id/condition_feelslike"
202+
android:layout_width="match_parent"
181203
android:layout_height="wrap_content"
182-
android:layout_alignParentTop="true"
183-
android:layout_alignParentBottom="true"
184-
android:layout_gravity="center_vertical|start"
185-
android:layout_marginStart="2dp"
186-
android:layout_toEndOf="@id/weather_icon"
187-
android:gravity="center_vertical"
204+
android:gravity="end"
205+
android:maxLines="1"
206+
android:paddingStart="4dp"
207+
android:paddingEnd="4dp"
188208
android:shadowColor="#000000"
189209
android:textColor="@android:color/white"
190-
android:textSize="28sp"
191-
tools:text="70°F" />
210+
android:textSize="12sp"
211+
tools:ignore="UnusedAttribute"
212+
tools:text="Feels like: 75°" />
192213

193-
</RelativeLayout>
214+
</LinearLayout>
194215

195216
</LinearLayout>
196217

0 commit comments

Comments
 (0)