Fix: Fixed error with fetchWeatherData not finding url.

Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
This commit is contained in:
HeCodes2Much
2024-07-05 20:51:08 +01:00
parent bdfa980621
commit 6d32eedbe1
2 changed files with 66 additions and 42 deletions

View File

@@ -26,10 +26,9 @@ import com.github.droidworksstudio.launcher.accessibility.ActionService
import com.github.droidworksstudio.launcher.helper.weather.WeatherResponse
import com.github.droidworksstudio.launcher.utils.WeatherApiService
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.net.UnknownHostException
import java.util.Calendar
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@@ -252,43 +251,52 @@ class AppHelper @Inject constructor() {
}
}
suspend fun fetchWeatherData(
sealed class WeatherResult {
data class Success(val weatherResponse: WeatherResponse) : WeatherResult()
data class Failure(val errorMessage: String) : WeatherResult()
}
fun fetchWeatherData(
context: Context,
latitude: Float,
longitude: Float
): WeatherResponse {
): WeatherResult {
// Check if cached data is available and not expired
val cachedWeatherData = context.getWeatherDataFromCache()
if (cachedWeatherData?.let { System.currentTimeMillis() - it.timestamp < TimeUnit.MINUTES.toMillis(15) } == true) {
return cachedWeatherData.weatherResponse
return WeatherResult.Success(cachedWeatherData.weatherResponse)
}
// Fetch weather data from the network
val apiKey = BuildConfig.API_KEY
val baseURL = "api.openweathermap.org"
val units = "metric"
val retrofit = Retrofit.Builder()
.baseUrl("https://api.openweathermap.org/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.build()
try {
val retrofit = Retrofit.Builder()
.baseUrl("https://$baseURL/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(WeatherApiService::class.java)
val service = retrofit.create(WeatherApiService::class.java)
return withContext(Dispatchers.IO) {
val response = service.getWeather("$latitude", "$longitude", units, apiKey).execute()
if (response.isSuccessful) {
val weatherResponse = response.body()
if (weatherResponse != null) {
// Cache the fetched weather data
context.cacheWeatherData(weatherResponse)
weatherResponse
return WeatherResult.Success(weatherResponse)
} else {
throw NullPointerException("Weather response body is null")
return WeatherResult.Failure("Weather response body is null")
}
} else {
throw Exception("Failed to fetch weather data: ${response.errorBody()}")
return WeatherResult.Failure("Failed to fetch weather data: ${response.errorBody()}")
}
} catch (e: UnknownHostException) {
return WeatherResult.Failure("Unknown Host : $baseURL")
} catch (e: Exception) {
return WeatherResult.Failure("${e.message}")
}
}

View File

@@ -28,6 +28,7 @@ import androidx.navigation.fragment.findNavController
import com.github.droidworksstudio.common.capitalizeEachWord
import com.github.droidworksstudio.common.hasInternetPermission
import com.github.droidworksstudio.common.hideKeyboard
import com.github.droidworksstudio.common.showLongToast
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.databinding.FragmentWidgetsBinding
import com.github.droidworksstudio.launcher.helper.AppHelper
@@ -36,7 +37,9 @@ import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
import com.github.droidworksstudio.launcher.utils.Constants
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -120,6 +123,7 @@ class WidgetFragment : Fragment(),
}
@OptIn(DelicateCoroutinesApi::class)
private fun setupWeatherWidget() {
val sharedPreferences =
context.getSharedPreferences(Constants.WEATHER_PREFS, Context.MODE_PRIVATE)
@@ -139,7 +143,9 @@ class WidgetFragment : Fragment(),
if (!showWeatherWidget || !context.hasInternetPermission()) return@launch
try {
val weatherDeferred = async { appHelper.fetchWeatherData(context, latitude, longitude) }
val weatherDeferred = GlobalScope.async {
appHelper.fetchWeatherData(context, latitude, longitude)
}
// Prepare UI elements concurrently
withContext(Dispatchers.Main) {
@@ -163,40 +169,50 @@ class WidgetFragment : Fragment(),
}
}
val weatherResponse = weatherDeferred.await()
Log.d("weatherResponse", "$weatherResponse")
val result = weatherDeferred.await()
Log.d("weatherResponse", "$result")
withContext(Dispatchers.Main) {
val timestamp = convertTimestampToReadableDate(weatherResponse.dt)
binding.apply {
weatherCity.text = getString(R.string.widget_weather_location, weatherResponse.name, weatherResponse.sys.country)
weatherTemperature.text = getString(R.string.widget_weather_temp, weatherResponse.main.temp, temperatureScale)
weatherDescription.text = getString(R.string.widget_weather_description, weatherResponse.weather[0].description).capitalizeEachWord()
weatherWind.text = getString(R.string.widget_weather_wind, weatherResponse.wind.speed, speedScale)
weatherHumidity.text = getString(R.string.widget_weather_humidity, weatherResponse.main.humidity)
weatherLastRun.text = timestamp
weatherRefresh.text = getString(R.string.widget_weather_refresh, getString(R.string.refresh_icon))
when (result) {
is AppHelper.WeatherResult.Success -> {
val weatherResponse = result.weatherResponse
val weatherIconBitmap = createWeatherIcon(context, setWeatherIcon(context, weatherResponse.weather[0].id))
weatherIcon.setImageBitmap(weatherIconBitmap) // Ensure this matches your ImageView ID
weatherIcon.setColorFilter(widgetTextColor)
withContext(Dispatchers.Main) {
val timestamp = convertTimestampToReadableDate(weatherResponse.dt)
binding.apply {
weatherCity.text = getString(R.string.widget_weather_location, weatherResponse.name, weatherResponse.sys.country)
weatherTemperature.text = getString(R.string.widget_weather_temp, weatherResponse.main.temp, temperatureScale)
weatherDescription.text = getString(R.string.widget_weather_description, weatherResponse.weather[0].description).capitalizeEachWord()
weatherWind.text = getString(R.string.widget_weather_wind, weatherResponse.wind.speed, speedScale)
weatherHumidity.text = getString(R.string.widget_weather_humidity, weatherResponse.main.humidity)
weatherLastRun.text = timestamp
weatherRefresh.text = getString(R.string.widget_weather_refresh, getString(R.string.refresh_icon))
val sunriseIconBitmap = createSunIcon(context, getString(R.string.sunrise_icon))
sunriseIcon.setImageBitmap(sunriseIconBitmap)
sunriseIcon.setColorFilter(widgetTextColor)
val weatherIconBitmap = createWeatherIcon(context, setWeatherIcon(context, weatherResponse.weather[0].id))
weatherIcon.setImageBitmap(weatherIconBitmap) // Ensure this matches your ImageView ID
weatherIcon.setColorFilter(widgetTextColor)
val sunsetIconBitmap = createSunIcon(context, getString(R.string.sunset_icon))
sunsetIcon.setImageBitmap(sunsetIconBitmap)
sunsetIcon.setColorFilter(widgetTextColor)
val sunriseIconBitmap = createSunIcon(context, getString(R.string.sunrise_icon))
sunriseIcon.setImageBitmap(sunriseIconBitmap)
sunriseIcon.setColorFilter(widgetTextColor)
val sunriseTime = convertTimestampToReadableDate(weatherResponse.sys.sunrise)
sunriseText.text = getString(R.string.widget_sunrise_time, sunriseTime)
val sunsetIconBitmap = createSunIcon(context, getString(R.string.sunset_icon))
sunsetIcon.setImageBitmap(sunsetIconBitmap)
sunsetIcon.setColorFilter(widgetTextColor)
val sunsetTime = convertTimestampToReadableDate(weatherResponse.sys.sunset)
sunsetText.text = getString(R.string.widget_sunset_time, sunsetTime)
val sunriseTime = convertTimestampToReadableDate(weatherResponse.sys.sunrise)
sunriseText.text = getString(R.string.widget_sunrise_time, sunriseTime)
val sunsetTime = convertTimestampToReadableDate(weatherResponse.sys.sunset)
sunsetText.text = getString(R.string.widget_sunset_time, sunsetTime)
weatherRoot.visibility = View.VISIBLE
weatherRoot.visibility = View.VISIBLE
}
}
}
is AppHelper.WeatherResult.Failure -> {
val errorMessage = result.errorMessage
context.showLongToast(errorMessage)
}
}
} catch (e: Exception) {