Fix: Fixed error with fetchWeatherData not finding url.
Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
This commit is contained in:
@@ -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}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user