Fix crashes when no Geocoder is available
This commit is contained in:
parent
b6259db33c
commit
5bace7d656
@ -9,6 +9,9 @@ import de.mm20.launcher2.ktx.putDouble
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A WeatherProvider that uses lat/lon locations only (instead of provider specific location IDs)
|
* A WeatherProvider that uses lat/lon locations only (instead of provider specific location IDs)
|
||||||
@ -21,7 +24,12 @@ abstract class LatLonWeatherProvider : WeatherProvider<LatLonWeatherLocation>()
|
|||||||
val geocoder = Geocoder(context)
|
val geocoder = Geocoder(context)
|
||||||
val locations =
|
val locations =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
geocoder.getFromLocationName(query, 10)
|
geocoder.getFromLocationName(query, 10)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
CrashReporter.logException(e)
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return locations.mapNotNull {
|
return locations.mapNotNull {
|
||||||
LatLonWeatherLocation(
|
LatLonWeatherLocation(
|
||||||
@ -37,9 +45,7 @@ abstract class LatLonWeatherProvider : WeatherProvider<LatLonWeatherLocation>()
|
|||||||
lon: Double
|
lon: Double
|
||||||
): WeatherUpdateResult<LatLonWeatherLocation>? {
|
): WeatherUpdateResult<LatLonWeatherLocation>? {
|
||||||
return try {
|
return try {
|
||||||
val locationName = Geocoder(context).getFromLocation(lat, lon, 1)
|
val locationName = getLocationName(lat, lon)
|
||||||
.firstOrNull()
|
|
||||||
?.formatToString() ?: "$lat/$lon"
|
|
||||||
loadWeatherData(
|
loadWeatherData(
|
||||||
LatLonWeatherLocation(
|
LatLonWeatherLocation(
|
||||||
name = locationName,
|
name = locationName,
|
||||||
@ -53,6 +59,39 @@ abstract class LatLonWeatherProvider : WeatherProvider<LatLonWeatherLocation>()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun getLocationName(lat: Double, lon: Double): String {
|
||||||
|
if (!Geocoder.isPresent()) return formatLatLon(lat, lon)
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
Geocoder(context).getFromLocation(lat, lon, 1)
|
||||||
|
.firstOrNull()
|
||||||
|
?.formatToString() ?: formatLatLon(lat, lon)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
CrashReporter.logException(e)
|
||||||
|
formatLatLon(lat, lon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatLatLon(lat: Double, lon: Double): String {
|
||||||
|
val absLat = lat.absoluteValue
|
||||||
|
val absLon = lon.absoluteValue
|
||||||
|
|
||||||
|
val dLat = absLat.toInt()
|
||||||
|
val dLon = absLon.toInt()
|
||||||
|
|
||||||
|
val mLat = ((absLat - dLat) * 60).roundToInt()
|
||||||
|
|
||||||
|
val mLon = ((absLon - dLon) * 60).roundToInt()
|
||||||
|
|
||||||
|
|
||||||
|
val dmsLat = "$dLat°$mLat'${if (lat >= 0) "N" else "S"}"
|
||||||
|
|
||||||
|
val dmsLon = "$dLon°$mLon'${if (lat >= 0) "E" else "W"}"
|
||||||
|
|
||||||
|
return "$dmsLat $dmsLon"
|
||||||
|
}
|
||||||
|
|
||||||
override fun setLocation(location: WeatherLocation?) {
|
override fun setLocation(location: WeatherLocation?) {
|
||||||
location as LatLonWeatherLocation?
|
location as LatLonWeatherLocation?
|
||||||
preferences.edit {
|
preferences.edit {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user