Add a few more providers and fix multiple bugs
BIN
.idea/caches/build_file_checksums.ser
generated
@ -23,8 +23,8 @@ android {
|
||||
applicationId "com.tommasoberlose.anotherwidget"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 29
|
||||
versionCode 105
|
||||
versionName "2.0.13"
|
||||
versionCode 106
|
||||
versionName "2.0.14"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
||||
|
@ -0,0 +1,64 @@
|
||||
package com.tommasoberlose.anotherwidget.components
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||
import kotlinx.android.synthetic.main.weather_provider_settings_layout.view.*
|
||||
|
||||
class BottomSheetWeatherProviderSettings(context: Context, callback: () -> Unit) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
|
||||
|
||||
init {
|
||||
val view = View.inflate(context, R.layout.weather_provider_settings_layout, null)
|
||||
view.api_key_container.isVisible = WeatherHelper.isKeyRequired()
|
||||
view.action_save_key.isVisible = WeatherHelper.isKeyRequired()
|
||||
|
||||
WeatherHelper.getProviderInfoTitle(context).let { title ->
|
||||
view.info_title.text = title
|
||||
view.info_title.isVisible = title != ""
|
||||
}
|
||||
|
||||
WeatherHelper.getProviderInfoSubtitle(context).let { subtitle ->
|
||||
view.info_subtitle.text = subtitle
|
||||
view.info_subtitle.isVisible = subtitle != ""
|
||||
}
|
||||
|
||||
view.info_provider.text = WeatherHelper.getProviderName(context)
|
||||
|
||||
view.api_key.editText?.setText(when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen
|
||||
Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit
|
||||
Constants.WeatherProvider.WEATHER_API -> Preferences.weatherProviderApiWeatherApi
|
||||
Constants.WeatherProvider.HERE -> Preferences.weatherProviderApiHere
|
||||
Constants.WeatherProvider.ACCUWEATHER -> Preferences.weatherProviderApiAccuweather
|
||||
Constants.WeatherProvider.WEATHER_GOV,
|
||||
Constants.WeatherProvider.YR,
|
||||
null -> ""
|
||||
})
|
||||
|
||||
view.action_open_provider.setOnClickListener {
|
||||
context.openURI(WeatherHelper.getProviderLink())
|
||||
}
|
||||
|
||||
view.action_save_key.setOnClickListener {
|
||||
val key = view.api_key.editText?.text.toString()
|
||||
when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen = key
|
||||
Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit = key
|
||||
Constants.WeatherProvider.WEATHER_API -> Preferences.weatherProviderApiWeatherApi = key
|
||||
Constants.WeatherProvider.HERE -> Preferences.weatherProviderApiHere = key
|
||||
Constants.WeatherProvider.ACCUWEATHER -> Preferences.weatherProviderApiAccuweather = key
|
||||
else -> {}
|
||||
}
|
||||
callback.invoke()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
setContentView(view)
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package com.tommasoberlose.anotherwidget.helpers
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
@ -12,6 +13,9 @@ import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
|
||||
@ -21,7 +25,7 @@ import org.greenrobot.eventbus.EventBus
|
||||
|
||||
object WeatherHelper {
|
||||
|
||||
fun updateWeather(context: Context) {
|
||||
suspend fun updateWeather(context: Context) {
|
||||
val networkApi = WeatherNetworkApi(context)
|
||||
if (Preferences.customLocationAdd != "") {
|
||||
networkApi.updateWeather()
|
||||
@ -32,10 +36,17 @@ object WeatherHelper {
|
||||
if (location != null) {
|
||||
Preferences.customLocationLat = location.latitude.toString()
|
||||
Preferences.customLocationLon = location.longitude.toString()
|
||||
|
||||
networkApi.updateWeather()
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
networkApi.updateWeather()
|
||||
}
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
} else {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
networkApi.updateWeather()
|
||||
}
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,7 +59,7 @@ object WeatherHelper {
|
||||
MainWidget.updateWidget(context)
|
||||
}
|
||||
|
||||
fun getProviderName(context: Context, provider: Constants.WeatherProvider): String {
|
||||
fun getProviderName(context: Context, provider: Constants.WeatherProvider = Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!): String {
|
||||
return context.getString(when(provider) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> R.string.settings_weather_provider_open_weather
|
||||
Constants.WeatherProvider.WEATHER_BIT -> R.string.settings_weather_provider_weatherbit
|
||||
@ -60,21 +71,8 @@ object WeatherHelper {
|
||||
})
|
||||
}
|
||||
|
||||
fun getProviderLinkName(context: Context): String {
|
||||
return context.getString(when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> R.string.action_open_provider_open_weather
|
||||
Constants.WeatherProvider.WEATHER_BIT -> R.string.action_open_provider_weatherbit
|
||||
Constants.WeatherProvider.WEATHER_API -> R.string.action_open_provider_weatherapi
|
||||
Constants.WeatherProvider.HERE -> R.string.action_open_provider_here
|
||||
Constants.WeatherProvider.ACCUWEATHER -> R.string.action_open_provider_accuweather
|
||||
Constants.WeatherProvider.WEATHER_GOV -> R.string.action_open_provider_weather_gov
|
||||
Constants.WeatherProvider.YR -> R.string.action_open_provider_yr
|
||||
else -> R.string.nothing
|
||||
})
|
||||
}
|
||||
|
||||
fun getProviderInfoTitle(context: Context): String {
|
||||
return context.getString(when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
fun getProviderInfoTitle(context: Context, provider: Constants.WeatherProvider? = Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!): String {
|
||||
return context.getString(when(provider) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> R.string.weather_provider_info_open_weather_title
|
||||
Constants.WeatherProvider.WEATHER_BIT -> R.string.weather_provider_info_weatherbit_title
|
||||
Constants.WeatherProvider.WEATHER_API -> R.string.weather_provider_info_weatherapi_title
|
||||
@ -86,8 +84,8 @@ object WeatherHelper {
|
||||
})
|
||||
}
|
||||
|
||||
fun getProviderInfoSubtitle(context: Context): String {
|
||||
return context.getString(when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
fun getProviderInfoSubtitle(context: Context, provider: Constants.WeatherProvider? = Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!): String {
|
||||
return context.getString(when(provider) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> R.string.weather_provider_info_open_weather_subtitle
|
||||
Constants.WeatherProvider.WEATHER_BIT -> R.string.weather_provider_info_weatherbit_subtitle
|
||||
Constants.WeatherProvider.WEATHER_API -> R.string.weather_provider_info_weatherapi_subtitle
|
||||
@ -99,20 +97,20 @@ object WeatherHelper {
|
||||
})
|
||||
}
|
||||
|
||||
fun getProviderLink(): String {
|
||||
return when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> "https://home.openweathermap.org/users/sign_up"
|
||||
Constants.WeatherProvider.WEATHER_BIT -> "https://www.weatherbit.io/account/create"
|
||||
Constants.WeatherProvider.WEATHER_API -> "https://www.weatherapi.com/signup.aspx"
|
||||
Constants.WeatherProvider.HERE -> "https://developer.here.com/sign-up?create=Freemium-Basic&keepState=true&step=account"
|
||||
Constants.WeatherProvider.ACCUWEATHER -> "https://developer.accuweather.com/user/register"
|
||||
fun getProviderLink(provider: Constants.WeatherProvider? = Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!): String {
|
||||
return when(provider) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> "https://home.openweathermap.org/users/sign_in"
|
||||
Constants.WeatherProvider.WEATHER_BIT -> "https://www.weatherbit.io/account/login"
|
||||
Constants.WeatherProvider.WEATHER_API -> "https://www.weatherapi.com/login.aspx"
|
||||
Constants.WeatherProvider.HERE -> "https://developer.here.com/login"
|
||||
Constants.WeatherProvider.ACCUWEATHER -> "https://developer.accuweather.com/user/login"
|
||||
Constants.WeatherProvider.WEATHER_GOV -> "http://www.weather.gov/"
|
||||
Constants.WeatherProvider.YR -> "https://www.yr.no/"
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun isKeyRequired(): Boolean = when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
fun isKeyRequired(provider: Constants.WeatherProvider? = Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!): Boolean = when (provider) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER,
|
||||
Constants.WeatherProvider.WEATHER_BIT,
|
||||
Constants.WeatherProvider.WEATHER_API,
|
||||
@ -124,6 +122,17 @@ object WeatherHelper {
|
||||
else -> true
|
||||
}
|
||||
|
||||
fun getApiKey(provider: Constants.WeatherProvider? = Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!): String = when (provider) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen
|
||||
Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit
|
||||
Constants.WeatherProvider.WEATHER_API -> Preferences.weatherProviderApiWeatherApi
|
||||
Constants.WeatherProvider.HERE -> Preferences.weatherProviderApiHere
|
||||
Constants.WeatherProvider.ACCUWEATHER -> Preferences.weatherProviderApiAccuweather
|
||||
Constants.WeatherProvider.WEATHER_GOV -> ""
|
||||
Constants.WeatherProvider.YR -> ""
|
||||
else -> ""
|
||||
}
|
||||
|
||||
fun getWeatherIconResource(context: Context, icon: String, style: Int = Preferences.weatherIconPack): Int {
|
||||
return when (icon) {
|
||||
"01d" -> {
|
||||
@ -451,4 +460,50 @@ object WeatherHelper {
|
||||
1282 -> "13"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
|
||||
fun getYRIcon(iconCode: String, isDaytime: Boolean): String = when {
|
||||
iconCode.contains("clearsky") -> "01"
|
||||
iconCode.contains("cloudy") -> "04"
|
||||
iconCode.contains("fair") -> "02"
|
||||
iconCode.contains("fog") -> "82"
|
||||
iconCode.contains("heavyrain") -> "10"
|
||||
iconCode.contains("heavyrainandthunder") -> "11"
|
||||
iconCode.contains("heavyrainshowers") -> "10"
|
||||
iconCode.contains("heavyrainshowersandthunder") -> "11"
|
||||
iconCode.contains("heavysleet") -> "10"
|
||||
iconCode.contains("heavysleetandthunder") -> "11"
|
||||
iconCode.contains("heavysleetshowers") -> "10"
|
||||
iconCode.contains("heavysleetshowersandthunder") -> "11"
|
||||
iconCode.contains("heavysnow") -> "13"
|
||||
iconCode.contains("heavysnowandthunder") -> "13"
|
||||
iconCode.contains("heavysnowshowers") -> "13"
|
||||
iconCode.contains("heavysnowshowersandthunder") -> "13"
|
||||
iconCode.contains("lightrain") -> "10"
|
||||
iconCode.contains("lightrainandthunder") -> "11"
|
||||
iconCode.contains("lightrainshowers") -> "10"
|
||||
iconCode.contains("lightrainshowersandthunder") -> "11"
|
||||
iconCode.contains("lightsleet") -> "10"
|
||||
iconCode.contains("lightsleetandthunder") -> "11"
|
||||
iconCode.contains("lightsleetshowers") -> "10"
|
||||
iconCode.contains("lightsnow") -> "13"
|
||||
iconCode.contains("lightsnowandthunder") -> "13"
|
||||
iconCode.contains("lightsnowshowers") -> "13"
|
||||
iconCode.contains("lightssleetshowersandthunder") -> "81"
|
||||
iconCode.contains("lightssnowshowersandthunder") -> "81"
|
||||
iconCode.contains("partlycloudy") -> "03"
|
||||
iconCode.contains("rain") -> "10"
|
||||
iconCode.contains("rainandthunder") -> "11"
|
||||
iconCode.contains("rainshowers") -> "10"
|
||||
iconCode.contains("rainshowersandthunder") -> "11"
|
||||
iconCode.contains("sleet") -> "10"
|
||||
iconCode.contains("sleetandthunder") -> "11"
|
||||
iconCode.contains("sleetshowers") -> "10"
|
||||
iconCode.contains("sleetshowersandthunder") -> "11"
|
||||
iconCode.contains("snow") -> "13"
|
||||
iconCode.contains("snowandthunder") -> "13"
|
||||
iconCode.contains("snowshowers") -> "13"
|
||||
iconCode.contains("snowshowersandthunder") -> "13"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
|
||||
}
|
@ -21,10 +21,12 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.lang.Exception
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class WeatherNetworkApi(val context: Context) {
|
||||
fun updateWeather() {
|
||||
Preferences.weatherProviderError = ""
|
||||
suspend fun updateWeather() {
|
||||
Preferences.weatherProviderError = "-"
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
if (Preferences.showWeather && Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
|
||||
@ -41,11 +43,13 @@ class WeatherNetworkApi(val context: Context) {
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useOpenWeatherMap(context: Context) {
|
||||
if (Preferences.weatherProviderApiOpen != "" ) {
|
||||
if (Preferences.weatherProviderApiOpen != "") {
|
||||
val helper = OpenWeatherMapHelper(Preferences.weatherProviderApiOpen)
|
||||
helper.setUnits(if (Preferences.weatherTempUnit == "F") Units.IMPERIAL else Units.METRIC)
|
||||
helper.getCurrentWeatherByGeoCoordinates(Preferences.customLocationLat.toDouble(), Preferences.customLocationLon.toDouble(), object :
|
||||
@ -56,14 +60,18 @@ class WeatherNetworkApi(val context: Context) {
|
||||
Preferences.weatherIcon = currentWeather.weather[0].icon
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
|
||||
override fun onFailure(throwable: Throwable?) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
@ -72,95 +80,137 @@ class WeatherNetworkApi(val context: Context) {
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useWeatherGov(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val repository = WeatherGovRepository()
|
||||
val pointsResponse = executeWithRetry(times = 5) {
|
||||
repository.getGridPoints(
|
||||
Preferences.customLocationLat,
|
||||
Preferences.customLocationLon
|
||||
)
|
||||
}
|
||||
private suspend fun useWeatherGov(context: Context) {
|
||||
val repository = WeatherGovRepository()
|
||||
val pointsResponse = executeWithRetry(times = 5) {
|
||||
repository.getGridPoints(
|
||||
Preferences.customLocationLat,
|
||||
Preferences.customLocationLon
|
||||
)
|
||||
}
|
||||
|
||||
when (pointsResponse) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val pp = pointsResponse.body["properties"] as LinkedTreeMap<*, *>
|
||||
val gridId = pp["gridId"] as String
|
||||
val gridX = pp["gridX"] as Double
|
||||
val gridY = pp["gridY"] as Double
|
||||
when (pointsResponse) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val pp = pointsResponse.body["properties"] as LinkedTreeMap<*, *>
|
||||
val gridId = pp["gridId"] as String
|
||||
val gridX = pp["gridX"] as Double
|
||||
val gridY = pp["gridY"] as Double
|
||||
|
||||
when (val weatherResponse = repository.getWeather(
|
||||
gridId,
|
||||
gridX,
|
||||
gridY,
|
||||
if (Preferences.weatherTempUnit == "F") "us" else "si"
|
||||
)) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val props =
|
||||
weatherResponse.body["properties"] as LinkedTreeMap<*, *>
|
||||
val periods = props["periods"] as List<*>
|
||||
val now = periods[0] as LinkedTreeMap<*, *>
|
||||
when (val weatherResponse = repository.getWeather(
|
||||
gridId,
|
||||
gridX,
|
||||
gridY,
|
||||
if (Preferences.weatherTempUnit == "F") "us" else "si"
|
||||
)) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val props =
|
||||
weatherResponse.body["properties"] as LinkedTreeMap<*, *>
|
||||
val periods = props["periods"] as List<*>
|
||||
val now = periods[0] as LinkedTreeMap<*, *>
|
||||
|
||||
val temp = now["temperature"] as Double
|
||||
val fullIcon = now["icon"] as String
|
||||
val isDaytime = now["isDaytime"] as Boolean
|
||||
val temp = now["temperature"] as Double
|
||||
val fullIcon = now["icon"] as String
|
||||
val isDaytime = now["isDaytime"] as Boolean
|
||||
|
||||
Preferences.weatherTemp = temp.toFloat()
|
||||
Preferences.weatherIcon = WeatherHelper.getWeatherGovIcon(fullIcon, isDaytime)
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
Preferences.weatherTemp = temp.toFloat()
|
||||
Preferences.weatherIcon = WeatherHelper.getWeatherGovIcon(fullIcon, isDaytime)
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
|
||||
MainWidget.updateWidget(context)
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
} catch (ex: Exception) {
|
||||
}
|
||||
MainWidget.updateWidget(context)
|
||||
} catch (ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
} catch(ex: Exception) {
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
if (pointsResponse.body?.containsKey("status") == true && (pointsResponse.body?.get("status") as Double).toInt() == 404) {
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_wrong_location)
|
||||
}
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
} catch(ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
if (pointsResponse.body?.containsKey("status") == true && (pointsResponse.body?.get("status") as Double).toInt() == 404) {
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_wrong_location)
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun useHereProvider(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
private suspend fun useHereProvider(context: Context) {
|
||||
if (Preferences.weatherProviderApiHere != "") {
|
||||
val repository = HereRepository()
|
||||
|
||||
when (val response = repository.getWeather()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
Log.d("ciao - here", response.body.toString())
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} catch(ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useWeatherBitProvider(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
private suspend fun useWeatherBitProvider(context: Context) {
|
||||
if (Preferences.weatherProviderApiWeatherBit != "") {
|
||||
val repository = WeatherbitRepository()
|
||||
|
||||
when (val response = repository.getWeather()) {
|
||||
@ -177,27 +227,53 @@ class WeatherNetworkApi(val context: Context) {
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
} catch(ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
when (response.code) {
|
||||
403 -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_invalid_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useWeatherApiProvider(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
private suspend fun useWeatherApiProvider(context: Context) {
|
||||
if (Preferences.weatherProviderApiWeatherApi != "") {
|
||||
val repository = WeatherApiRepository()
|
||||
|
||||
when (val response = repository.getWeather()) {
|
||||
@ -216,68 +292,150 @@ class WeatherNetworkApi(val context: Context) {
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
} catch(ex: Exception) {
|
||||
Log.d("ciao", ex.localizedMessage)
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
when (response.code) {
|
||||
401 -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_invalid_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
403 -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_expired_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useAccuweatherProvider(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val repository = AccuweatherRepository()
|
||||
private suspend fun useAccuweatherProvider(context: Context) {
|
||||
if (Preferences.weatherProviderApiAccuweather != "") {
|
||||
val repository = AccuweatherRepository()
|
||||
|
||||
// when (val response = repository.getWeather()) {
|
||||
// is NetworkResponse.Success -> {
|
||||
// try {
|
||||
// Log.d("ciao", response.body.toString())
|
||||
// } catch(ex: Exception) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// is NetworkResponse.ServerError -> {
|
||||
// WeatherHelper.removeWeather(
|
||||
// context
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// when (val response = repository.getWeather()) {
|
||||
// is NetworkResponse.Success -> {
|
||||
// try {
|
||||
// Log.d("ciao", response.body.toString())
|
||||
// } catch(ex: Exception) {
|
||||
//
|
||||
// Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
// Preferences.weatherProviderLocationError = ""
|
||||
// }
|
||||
// }
|
||||
// is NetworkResponse.ServerError -> {
|
||||
// WeatherHelper.removeWeather(
|
||||
// context
|
||||
// )
|
||||
// }
|
||||
// Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
// Preferences.weatherProviderLocationError = ""
|
||||
// EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
// }
|
||||
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useYrProvider(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val repository = YrRepository()
|
||||
private suspend fun useYrProvider(context: Context) {
|
||||
val repository = YrRepository()
|
||||
|
||||
when (val response = repository.getWeather()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
Log.d("ciao - yr", response.body.toString())
|
||||
} catch(ex: Exception) {
|
||||
when (val response = repository.getWeather()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val pp = response.body["properties"] as LinkedTreeMap<*, *>
|
||||
val data = pp["timeseries"] as List<LinkedTreeMap<String, Any>>?
|
||||
data?.let {
|
||||
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||
for (item in data) {
|
||||
val time = Calendar.getInstance().apply { time = format.parse(item["time"] as String)!! }
|
||||
val now = Calendar.getInstance()
|
||||
if (time.timeInMillis >= now.timeInMillis) {
|
||||
val dd = item["data"] as LinkedTreeMap<*, *>
|
||||
val instant = dd["instant"] as LinkedTreeMap<*, *>
|
||||
val next = dd["next_1_hours"] as LinkedTreeMap<*, *>
|
||||
|
||||
val details = instant["details"] as LinkedTreeMap<*, *>
|
||||
val temp = details["air_temperature"] as Double
|
||||
|
||||
val summary = next["summary"] as LinkedTreeMap<*, *>
|
||||
val iconCode = summary["symbol_code"] as String
|
||||
|
||||
Preferences.weatherTemp = temp.toFloat()
|
||||
Preferences.weatherIcon = WeatherHelper.getYRIcon(iconCode, now.get(Calendar.HOUR_OF_DAY) >= 22 || now.get(Calendar.HOUR_OF_DAY) <= 8)
|
||||
Preferences.weatherTempUnit = "C"
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch(ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ import android.content.Intent
|
||||
import com.tommasoberlose.anotherwidget.global.Actions
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
|
||||
@ -22,7 +25,9 @@ class WeatherReceiver : BroadcastReceiver() {
|
||||
Intent.ACTION_TIME_CHANGED -> setUpdates(context)
|
||||
|
||||
Actions.ACTION_WEATHER_UPDATE -> {
|
||||
WeatherHelper.updateWeather(context)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
WeatherHelper.updateWeather(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,10 @@ import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
@ -15,37 +17,44 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetWeatherProviderSettings
|
||||
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
|
||||
import com.tommasoberlose.anotherwidget.databinding.ActivityWeatherProviderBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.ChooseApplicationViewModel
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.WeatherProviderViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.collapse
|
||||
import com.tommasoberlose.anotherwidget.utils.expand
|
||||
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||
import kotlinx.android.synthetic.main.activity_choose_application.*
|
||||
import com.tommasoberlose.anotherwidget.utils.reveal
|
||||
import kotlinx.android.synthetic.main.activity_weather_provider.*
|
||||
import kotlinx.android.synthetic.main.activity_weather_provider.action_back
|
||||
import kotlinx.android.synthetic.main.activity_weather_provider.list_view
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class WeatherProviderActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var adapter: SlimAdapter
|
||||
private lateinit var viewModel: MainViewModel
|
||||
private lateinit var viewModel: WeatherProviderViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_weather_provider)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
|
||||
api_key.editText?.setText(Preferences.weatherProviderApiOpen)
|
||||
viewModel = ViewModelProvider(this).get(WeatherProviderViewModel::class.java)
|
||||
|
||||
list_view.setHasFixedSize(true)
|
||||
val mLayoutManager = LinearLayoutManager(this)
|
||||
@ -53,91 +62,119 @@ class WeatherProviderActivity : AppCompatActivity() {
|
||||
|
||||
adapter = SlimAdapter.create()
|
||||
adapter
|
||||
.register<Int>(R.layout.list_item) { item, injector ->
|
||||
val provider = Constants.WeatherProvider.fromInt(item)!!
|
||||
.register<Constants.WeatherProvider>(R.layout.weather_provider_list_item) { provider, injector ->
|
||||
injector
|
||||
.text(R.id.text, WeatherHelper.getProviderName(this, provider))
|
||||
.clicked(R.id.text) {
|
||||
Preferences.weatherProvider = item
|
||||
.clicked(R.id.item) {
|
||||
val oldValue = Preferences.weatherProvider
|
||||
Preferences.weatherProvider = provider.value
|
||||
updateListItem(oldValue)
|
||||
updateListItem()
|
||||
loader.isVisible = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||
}
|
||||
}
|
||||
}
|
||||
.attachTo(list_view)
|
||||
.clicked(R.id.radioButton) {
|
||||
val oldValue = Preferences.weatherProvider
|
||||
Preferences.weatherProvider = provider.value
|
||||
updateListItem(oldValue)
|
||||
updateListItem()
|
||||
loader.isVisible = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||
}
|
||||
}
|
||||
.checked(R.id.radioButton, provider.value == Preferences.weatherProvider)
|
||||
.with<TextView>(R.id.text2) {
|
||||
if (WeatherHelper.isKeyRequired(provider)) {
|
||||
it.text = getString(R.string.api_key_required_message)
|
||||
}
|
||||
|
||||
if (provider == Constants.WeatherProvider.WEATHER_GOV) {
|
||||
it.text = getString(R.string.us_only_message)
|
||||
}
|
||||
}
|
||||
.clicked(R.id.action_configure) {
|
||||
BottomSheetWeatherProviderSettings(this) {
|
||||
lifecycleScope.launch {
|
||||
loader.isVisible = true
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
.visibility(R.id.action_configure, if (/*WeatherHelper.isKeyRequired(provider) && */provider.value == Preferences.weatherProvider) View.VISIBLE else View.GONE)
|
||||
.visibility(R.id.info_container, if (WeatherHelper.isKeyRequired(provider) || provider == Constants.WeatherProvider.WEATHER_GOV) View.VISIBLE else View.GONE)
|
||||
.with<TextView>(R.id.provider_error) {
|
||||
if (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-") {
|
||||
it.text = Preferences.weatherProviderError
|
||||
it.isVisible = provider.value == Preferences.weatherProvider
|
||||
} else if (Preferences.weatherProviderLocationError != "") {
|
||||
it.text = Preferences.weatherProviderLocationError
|
||||
it.isVisible = provider.value == Preferences.weatherProvider
|
||||
} else {
|
||||
it.isVisible = false
|
||||
}
|
||||
}
|
||||
.image(R.id.action_configure, ContextCompat.getDrawable(this, if (WeatherHelper.isKeyRequired(provider)) R.drawable.round_settings else R.drawable.outline_info_white))
|
||||
}.attachTo(list_view)
|
||||
|
||||
adapter.updateData(
|
||||
Constants.WeatherProvider.values().asList()
|
||||
.filter { it != Constants.WeatherProvider.HERE }
|
||||
.filter { it != Constants.WeatherProvider.ACCUWEATHER }
|
||||
)
|
||||
|
||||
setupListener()
|
||||
subscribeUi(viewModel)
|
||||
}
|
||||
|
||||
private fun subscribeUi(viewModel: MainViewModel) {
|
||||
adapter.updateData(Constants.WeatherProvider.values().map { it.value })
|
||||
private fun subscribeUi(viewModel: WeatherProviderViewModel) {
|
||||
viewModel.weatherProviderError.observe(this) {
|
||||
updateListItem()
|
||||
}
|
||||
|
||||
// viewModel.weatherProvider.observe(this, Observer {
|
||||
// weather_provider.editText?.setText(WeatherHelper.getProviderName(this, Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!).split("\n").first())
|
||||
//
|
||||
// api_key_container.isVisible = WeatherHelper.isKeyRequired()
|
||||
//
|
||||
// WeatherHelper.getProviderInfoTitle(this).let {
|
||||
// info_title.text = it
|
||||
// info_title.isVisible = it != ""
|
||||
// }
|
||||
//
|
||||
// WeatherHelper.getProviderInfoSubtitle(this).let {
|
||||
// info_subtitle.text = it
|
||||
// info_subtitle.isVisible = it != ""
|
||||
// }
|
||||
//
|
||||
// action_open_provider.text = WeatherHelper.getProviderLinkName(this)
|
||||
//
|
||||
// api_key.editText?.setText(when (Constants.WeatherProvider.fromInt(it)) {
|
||||
// Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen
|
||||
// Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit
|
||||
// Constants.WeatherProvider.WEATHER_API -> Preferences.weatherProviderApiWeatherApi
|
||||
// Constants.WeatherProvider.HERE -> Preferences.weatherProviderApiHere
|
||||
// Constants.WeatherProvider.ACCUWEATHER -> Preferences.weatherProviderApiAccuweather
|
||||
// Constants.WeatherProvider.WEATHER_GOV,
|
||||
// Constants.WeatherProvider.YR,
|
||||
// null -> ""
|
||||
// })
|
||||
// })
|
||||
viewModel.weatherProviderLocationError.observe(this) {
|
||||
updateListItem()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateListItem(provider: Int = Preferences.weatherProvider) {
|
||||
(adapter.data).forEachIndexed { index, item ->
|
||||
if (item is Constants.WeatherProvider && item.value == provider) {
|
||||
adapter.notifyItemChanged(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
action_back.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
action_open_provider.setOnClickListener {
|
||||
openURI(WeatherHelper.getProviderLink())
|
||||
}
|
||||
|
||||
weather_provider_inner.setOnClickListener {
|
||||
if (Preferences.showWeather) {
|
||||
val dialog = BottomSheetMenu<Int>(this, header = getString(R.string.settings_weather_provider_api)).setSelectedValue(Preferences.weatherProvider)
|
||||
(0 until 7).forEach {
|
||||
val item = Constants.WeatherProvider.fromInt(it)
|
||||
dialog.addItem(WeatherHelper.getProviderName(this, item!!), it)
|
||||
}
|
||||
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.weatherProvider = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
api_key.editText?.addTextChangedListener {
|
||||
val key = it?.toString() ?: ""
|
||||
when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen = key
|
||||
Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit = key
|
||||
Constants.WeatherProvider.WEATHER_API -> Preferences.weatherProviderApiWeatherApi = key
|
||||
Constants.WeatherProvider.HERE -> Preferences.weatherProviderApiHere = key
|
||||
Constants.WeatherProvider.ACCUWEATHER -> Preferences.weatherProviderApiAccuweather = key
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
EventBus.getDefault().unregister(this)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onMessageEvent(ignore: MainFragment.UpdateUiMessageEvent?) {
|
||||
loader.isVisible = Preferences.weatherProviderError == "-"
|
||||
if (Preferences.weatherProviderError == "" && Preferences.weatherProviderLocationError == "") {
|
||||
Snackbar.make(list_view, getString(R.string.settings_weather_provider_api_key_subtitle_all_set), Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,7 @@ import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import com.tommasoberlose.anotherwidget.utils.getCurrentWallpaper
|
||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||
import com.tommasoberlose.anotherwidget.utils.*
|
||||
import kotlinx.android.synthetic.main.fragment_app_main.*
|
||||
import kotlinx.android.synthetic.main.the_widget_sans.*
|
||||
import kotlinx.coroutines.*
|
||||
@ -76,6 +73,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
subscribeUi(viewModel)
|
||||
|
||||
// Viewpager
|
||||
@ -352,11 +350,11 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
|
||||
badgeGravity = BadgeDrawable.TOP_END
|
||||
}?.isVisible = if (Preferences.showWeather) {
|
||||
(WeatherHelper.isKeyRequired() && Preferences.weatherProviderApiOpen == "")
|
||||
(WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "")
|
||||
|| (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
||||
) != true)
|
||||
|| (Preferences.weatherProviderError != "")
|
||||
|| (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -193,7 +193,9 @@ class SettingsFragment : Fragment() {
|
||||
}
|
||||
|
||||
action_refresh_widget.setOnClickListener {
|
||||
WeatherHelper.updateWeather(requireContext())
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
WeatherHelper.updateWeather(requireContext())
|
||||
}
|
||||
CalendarHelper.updateEventList(requireContext())
|
||||
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ class WeatherTabFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun checkWeatherProviderConfig() {
|
||||
weather_provider_error.isVisible = Preferences.weatherProviderError != ""
|
||||
weather_provider_error.isVisible = Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-"
|
||||
weather_provider_error?.text = Preferences.weatherProviderError
|
||||
|
||||
weather_provider_location_error.isVisible = Preferences.weatherProviderLocationError != ""
|
||||
@ -233,7 +233,9 @@ class WeatherTabFragment : Fragment() {
|
||||
.addItem(getString(R.string.celsius), "C")
|
||||
.addOnSelectItemListener { value ->
|
||||
if (value != Preferences.weatherTempUnit) {
|
||||
WeatherHelper.updateWeather(requireContext())
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
WeatherHelper.updateWeather(requireContext())
|
||||
}
|
||||
}
|
||||
Preferences.weatherTempUnit = value
|
||||
}.show()
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.chibatching.kotpref.livedata.asLiveData
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
|
||||
class WeatherProviderViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
val weatherProvider = Preferences.asLiveData(Preferences::weatherProvider)
|
||||
val weatherProviderError = Preferences.asLiveData(Preferences::weatherProviderError)
|
||||
val weatherProviderLocationError = Preferences.asLiveData(Preferences::weatherProviderLocationError)
|
||||
|
||||
|
||||
}
|
@ -32,10 +32,7 @@ import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.*
|
||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
||||
import com.tommasoberlose.anotherwidget.receivers.*
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import com.tommasoberlose.anotherwidget.utils.getCapWordString
|
||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||
import com.tommasoberlose.anotherwidget.utils.*
|
||||
import kotlinx.android.synthetic.main.the_widget.view.*
|
||||
import java.lang.Exception
|
||||
import java.text.DateFormat
|
||||
@ -661,14 +658,11 @@ class MainWidget : AppWidgetProvider() {
|
||||
if (Preferences.isCharging) {
|
||||
v.second_row_icon.isVisible = false
|
||||
val batteryLevel = BatteryHelper.getBatteryLevel(context)
|
||||
if (batteryLevel == 100) {
|
||||
v.next_event_date.text = "%s - %d%%".format(
|
||||
context.getString(R.string.charging),
|
||||
batteryLevel
|
||||
)
|
||||
if (batteryLevel != 100) {
|
||||
v.next_event_date.text = context.getString(R.string.charging)
|
||||
} else {
|
||||
v.next_event_date.text =
|
||||
context.getString(R.string.charging)
|
||||
context.getString(R.string.charged)
|
||||
}
|
||||
showSomething = true
|
||||
break@loop
|
||||
|
@ -95,7 +95,7 @@ fun View.expand() {
|
||||
}
|
||||
}
|
||||
|
||||
fun View.collapse() {
|
||||
fun View.collapse(duration: Long = 500L) {
|
||||
if (visibility != View.GONE) {
|
||||
val initialHeight = measuredHeight
|
||||
|
||||
@ -114,7 +114,7 @@ fun View.collapse() {
|
||||
}
|
||||
}
|
||||
|
||||
a.duration = 500L //(initialHeight / v.context.resources.displayMetrics.density).toLong()
|
||||
a.duration = duration //(initialHeight / v.context.resources.displayMetrics.density).toLong()
|
||||
startAnimation(a)
|
||||
}
|
||||
}
|
||||
|
BIN
app/src/main/res/drawable-hdpi/round_call_made.png
Normal file
After Width: | Height: | Size: 273 B |
BIN
app/src/main/res/drawable-hdpi/round_call_made_white_18.png
Normal file
After Width: | Height: | Size: 184 B |
BIN
app/src/main/res/drawable-hdpi/round_call_made_white_24.png
Normal file
After Width: | Height: | Size: 195 B |
BIN
app/src/main/res/drawable-hdpi/round_call_made_white_48.png
Normal file
After Width: | Height: | Size: 295 B |
BIN
app/src/main/res/drawable-hdpi/round_close_white_18.png
Normal file
After Width: | Height: | Size: 196 B |
BIN
app/src/main/res/drawable-hdpi/round_close_white_24.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
app/src/main/res/drawable-hdpi/round_close_white_36.png
Normal file
After Width: | Height: | Size: 292 B |
BIN
app/src/main/res/drawable-hdpi/round_close_white_48.png
Normal file
After Width: | Height: | Size: 379 B |
BIN
app/src/main/res/drawable-hdpi/round_language.png
Normal file
After Width: | Height: | Size: 472 B |
BIN
app/src/main/res/drawable-hdpi/round_language_white_24.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
app/src/main/res/drawable-hdpi/round_language_white_36.png
Normal file
After Width: | Height: | Size: 871 B |
BIN
app/src/main/res/drawable-hdpi/round_language_white_48.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-hdpi/round_pageview_white_18.png
Normal file
After Width: | Height: | Size: 296 B |
BIN
app/src/main/res/drawable-hdpi/round_pageview_white_24.png
Normal file
After Width: | Height: | Size: 365 B |
BIN
app/src/main/res/drawable-hdpi/round_pageview_white_36.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
app/src/main/res/drawable-hdpi/round_pageview_white_48.png
Normal file
After Width: | Height: | Size: 614 B |
BIN
app/src/main/res/drawable-hdpi/round_public.png
Normal file
After Width: | Height: | Size: 952 B |
BIN
app/src/main/res/drawable-hdpi/round_public_white_18.png
Normal file
After Width: | Height: | Size: 450 B |
BIN
app/src/main/res/drawable-hdpi/round_public_white_24.png
Normal file
After Width: | Height: | Size: 502 B |
BIN
app/src/main/res/drawable-hdpi/round_public_white_36.png
Normal file
After Width: | Height: | Size: 758 B |
BIN
app/src/main/res/drawable-hdpi/round_search.png
Normal file
After Width: | Height: | Size: 676 B |
BIN
app/src/main/res/drawable-hdpi/round_search_white_18.png
Normal file
After Width: | Height: | Size: 314 B |
BIN
app/src/main/res/drawable-hdpi/round_search_white_24.png
Normal file
After Width: | Height: | Size: 380 B |
BIN
app/src/main/res/drawable-hdpi/round_search_white_36.png
Normal file
After Width: | Height: | Size: 557 B |
BIN
app/src/main/res/drawable-mdpi/round_call_made.png
Normal file
After Width: | Height: | Size: 195 B |
BIN
app/src/main/res/drawable-mdpi/round_call_made_white_18.png
Normal file
After Width: | Height: | Size: 154 B |
BIN
app/src/main/res/drawable-mdpi/round_call_made_white_24.png
Normal file
After Width: | Height: | Size: 149 B |
BIN
app/src/main/res/drawable-mdpi/round_call_made_white_48.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
app/src/main/res/drawable-mdpi/round_close_white_18.png
Normal file
After Width: | Height: | Size: 153 B |
BIN
app/src/main/res/drawable-mdpi/round_close_white_24.png
Normal file
After Width: | Height: | Size: 186 B |
BIN
app/src/main/res/drawable-mdpi/round_close_white_36.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
app/src/main/res/drawable-mdpi/round_close_white_48.png
Normal file
After Width: | Height: | Size: 297 B |
BIN
app/src/main/res/drawable-mdpi/round_language.png
Normal file
After Width: | Height: | Size: 333 B |
BIN
app/src/main/res/drawable-mdpi/round_language_white_24.png
Normal file
After Width: | Height: | Size: 400 B |
BIN
app/src/main/res/drawable-mdpi/round_language_white_36.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
app/src/main/res/drawable-mdpi/round_language_white_48.png
Normal file
After Width: | Height: | Size: 777 B |
BIN
app/src/main/res/drawable-mdpi/round_pageview_white_18.png
Normal file
After Width: | Height: | Size: 222 B |
BIN
app/src/main/res/drawable-mdpi/round_pageview_white_24.png
Normal file
After Width: | Height: | Size: 248 B |
BIN
app/src/main/res/drawable-mdpi/round_pageview_white_36.png
Normal file
After Width: | Height: | Size: 365 B |
BIN
app/src/main/res/drawable-mdpi/round_pageview_white_48.png
Normal file
After Width: | Height: | Size: 432 B |
BIN
app/src/main/res/drawable-mdpi/round_public.png
Normal file
After Width: | Height: | Size: 635 B |
BIN
app/src/main/res/drawable-mdpi/round_public_white_18.png
Normal file
After Width: | Height: | Size: 307 B |
BIN
app/src/main/res/drawable-mdpi/round_public_white_24.png
Normal file
After Width: | Height: | Size: 346 B |
BIN
app/src/main/res/drawable-mdpi/round_public_white_36.png
Normal file
After Width: | Height: | Size: 502 B |
BIN
app/src/main/res/drawable-mdpi/round_search.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
app/src/main/res/drawable-mdpi/round_search_white_18.png
Normal file
After Width: | Height: | Size: 243 B |
BIN
app/src/main/res/drawable-mdpi/round_search_white_24.png
Normal file
After Width: | Height: | Size: 276 B |
BIN
app/src/main/res/drawable-mdpi/round_search_white_36.png
Normal file
After Width: | Height: | Size: 380 B |
BIN
app/src/main/res/drawable-xhdpi/round_call_made.png
Normal file
After Width: | Height: | Size: 295 B |
BIN
app/src/main/res/drawable-xhdpi/round_call_made_white_18.png
Normal file
After Width: | Height: | Size: 195 B |
BIN
app/src/main/res/drawable-xhdpi/round_call_made_white_24.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
app/src/main/res/drawable-xhdpi/round_call_made_white_48.png
Normal file
After Width: | Height: | Size: 381 B |
BIN
app/src/main/res/drawable-xhdpi/round_close_white_18.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
app/src/main/res/drawable-xhdpi/round_close_white_24.png
Normal file
After Width: | Height: | Size: 297 B |
BIN
app/src/main/res/drawable-xhdpi/round_close_white_36.png
Normal file
After Width: | Height: | Size: 379 B |
BIN
app/src/main/res/drawable-xhdpi/round_close_white_48.png
Normal file
After Width: | Height: | Size: 485 B |
BIN
app/src/main/res/drawable-xhdpi/round_language.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
app/src/main/res/drawable-xhdpi/round_language_white_24.png
Normal file
After Width: | Height: | Size: 777 B |
BIN
app/src/main/res/drawable-xhdpi/round_language_white_36.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/round_language_white_48.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xhdpi/round_pageview_white_18.png
Normal file
After Width: | Height: | Size: 365 B |
BIN
app/src/main/res/drawable-xhdpi/round_pageview_white_24.png
Normal file
After Width: | Height: | Size: 432 B |
BIN
app/src/main/res/drawable-xhdpi/round_pageview_white_36.png
Normal file
After Width: | Height: | Size: 614 B |
BIN
app/src/main/res/drawable-xhdpi/round_pageview_white_48.png
Normal file
After Width: | Height: | Size: 807 B |
BIN
app/src/main/res/drawable-xhdpi/round_public.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/round_public_white_18.png
Normal file
After Width: | Height: | Size: 502 B |
BIN
app/src/main/res/drawable-xhdpi/round_public_white_24.png
Normal file
After Width: | Height: | Size: 635 B |
BIN
app/src/main/res/drawable-xhdpi/round_public_white_36.png
Normal file
After Width: | Height: | Size: 952 B |
BIN
app/src/main/res/drawable-xhdpi/round_search.png
Normal file
After Width: | Height: | Size: 877 B |
BIN
app/src/main/res/drawable-xhdpi/round_search_white_18.png
Normal file
After Width: | Height: | Size: 380 B |
BIN
app/src/main/res/drawable-xhdpi/round_search_white_24.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
app/src/main/res/drawable-xhdpi/round_search_white_36.png
Normal file
After Width: | Height: | Size: 676 B |
BIN
app/src/main/res/drawable-xxhdpi/round_call_made.png
Normal file
After Width: | Height: | Size: 437 B |
BIN
app/src/main/res/drawable-xxhdpi/round_call_made_white_18.png
Normal file
After Width: | Height: | Size: 273 B |
BIN
app/src/main/res/drawable-xxhdpi/round_call_made_white_24.png
Normal file
After Width: | Height: | Size: 295 B |
BIN
app/src/main/res/drawable-xxhdpi/round_call_made_white_48.png
Normal file
After Width: | Height: | Size: 568 B |
BIN
app/src/main/res/drawable-xxhdpi/round_close_white_18.png
Normal file
After Width: | Height: | Size: 292 B |
BIN
app/src/main/res/drawable-xxhdpi/round_close_white_24.png
Normal file
After Width: | Height: | Size: 379 B |
BIN
app/src/main/res/drawable-xxhdpi/round_close_white_36.png
Normal file
After Width: | Height: | Size: 509 B |
BIN
app/src/main/res/drawable-xxhdpi/round_close_white_48.png
Normal file
After Width: | Height: | Size: 689 B |
BIN
app/src/main/res/drawable-xxhdpi/round_language.png
Normal file
After Width: | Height: | Size: 871 B |
BIN
app/src/main/res/drawable-xxhdpi/round_language_white_24.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xxhdpi/round_language_white_36.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xxhdpi/round_language_white_48.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable-xxhdpi/round_pageview_white_18.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
app/src/main/res/drawable-xxhdpi/round_pageview_white_24.png
Normal file
After Width: | Height: | Size: 614 B |
BIN
app/src/main/res/drawable-xxhdpi/round_pageview_white_36.png
Normal file
After Width: | Height: | Size: 893 B |