Add some providers

This commit is contained in:
Tommaso Berlose 2020-10-04 11:43:36 +02:00
parent c04040e242
commit 1dee4cc8e5
34 changed files with 213 additions and 3 deletions

Binary file not shown.

View File

@ -112,6 +112,15 @@ dependencies {
implementation "androidx.palette:palette-ktx:1.0.0"
implementation 'androidx.core:core-ktx:1.3.2'
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'
//Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5'
// Add the Firebase SDK for Crashlytics.
implementation 'com.google.firebase:firebase-crashlytics:17.2.2'

View File

@ -36,6 +36,25 @@ object Constants {
HIGH(2)
}
enum class WeatherProvider(val value: Int) {
OPEN_WEATHER(0),
WEATHER_BIT(1),
FORECA(2),
HERE(3),
ACCUWEATHER(4),
WEATHER_GOV(5),
YR(6),
SMHI(7),
WEATHER_CA(8),
BOM(9),
METEOFRANCE(10);
companion object {
private val map = WeatherProvider.values().associateBy(WeatherProvider::value)
fun fromInt(type: Int) = map[type]
}
}
enum class WeatherIconPack(val value: Int) {
DEFAULT(0),
MINIMAL(1),

View File

@ -39,6 +39,7 @@ object Preferences : KotprefModel() {
var weatherAppName by stringPref(key = "PREF_WEATHER_APP_NAME", default = "")
var weatherAppPackage by stringPref(key = "PREF_WEATHER_APP_PACKAGE", default = "")
var weatherProviderApi by stringPref(key = "PREF_WEATHER_PROVIDER_API_KEY", default = "")
var weatherProvider by intPref(default = Constants.WeatherProvider.OPEN_WEATHER.value)
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
var eventAppPackage by stringPref(key = "PREF_EVENT_APP_PACKAGE", default = "")
var openEventDetails by booleanPref(default = true)

View File

@ -46,6 +46,22 @@ object WeatherHelper {
MainWidget.updateWidget(context)
}
fun getProviderName(context: Context, provider: Constants.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
Constants.WeatherProvider.FORECA -> R.string.settings_weather_provider_foreca
Constants.WeatherProvider.HERE -> R.string.settings_weather_provider_here
Constants.WeatherProvider.ACCUWEATHER -> R.string.settings_weather_provider_accuweather
Constants.WeatherProvider.WEATHER_GOV -> R.string.settings_weather_provider_weather_gov
Constants.WeatherProvider.YR -> R.string.settings_weather_provider_yr
Constants.WeatherProvider.SMHI -> R.string.settings_weather_provider_smhi
Constants.WeatherProvider.WEATHER_CA -> R.string.settings_weather_provider_weather_ca
Constants.WeatherProvider.BOM -> R.string.settings_weather_provider_bom
Constants.WeatherProvider.METEOFRANCE -> R.string.settings_weather_provider_meteofrance
})
}
fun getWeatherIconResource(icon: String, style: Int = Preferences.weatherIconPack): Int {
return when (icon) {
"01d" -> {

View File

@ -1,19 +1,41 @@
package com.tommasoberlose.anotherwidget.network
import android.content.Context
import android.util.Log
import com.google.gson.internal.LinkedTreeMap
import com.kwabenaberko.openweathermaplib.constants.Units
import com.kwabenaberko.openweathermaplib.implementation.OpenWeatherMapHelper
import com.kwabenaberko.openweathermaplib.implementation.callbacks.CurrentWeatherCallback
import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.network.repository.WeatherGovRepository
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import java.lang.Exception
class WeatherNetworkApi(val context: Context) {
fun updateWeather() {
if (Preferences.showWeather && Preferences.weatherProviderApi != "" && Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
if (Preferences.showWeather && Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> useOpenWeatherMap(context)
Constants.WeatherProvider.WEATHER_GOV -> useWeatherGov(context)
}
} else {
WeatherHelper.removeWeather(
context
)
}
}
private fun useOpenWeatherMap(context: Context) {
if (Preferences.weatherProviderApi != "" ) {
val helper = OpenWeatherMapHelper(Preferences.weatherProviderApi)
helper.setUnits(if (Preferences.weatherTempUnit == "F") Units.IMPERIAL else Units.METRIC)
helper.getCurrentWeatherByGeoCoordinates(Preferences.customLocationLat.toDouble(), Preferences.customLocationLon.toDouble(), object :
@ -39,4 +61,27 @@ class WeatherNetworkApi(val context: Context) {
)
}
}
private fun useWeatherGov(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
val repository = WeatherGovRepository()
try {
val points = repository.getGridPoints(
Preferences.customLocationLat,
Preferences.customLocationLon
)
val pp = points["properties"] as LinkedTreeMap<*,*>
val gridId = pp["gridId"] as String
val gridX = pp["gridX"] as Double
val gridY = pp["gridY"] as Double
val weather = repository.getWeather(gridId, gridX, gridY)
Log.d("ciao", weather.toString())
} catch (ex: Exception) {
Log.d("ciao", ex.localizedMessage)
}
}
}
}

View File

@ -0,0 +1,12 @@
package com.tommasoberlose.anotherwidget.network.api
import retrofit2.http.GET
import retrofit2.http.Path
interface WeatherGovApiService {
@GET("points/{latitude},{longitude}")
suspend fun getGridPoints(@Path("latitude") latitude: String, @Path("longitude") longitude: String): HashMap<String, Any>
@GET("gridpoints/{gridId}/{gridX},{gridY}/forecast")
suspend fun getWeather(@Path("gridId") gridId: String, @Path("gridX") gridX: Int, @Path("gridY") gridY: Int): HashMap<String, Any>
}

View File

@ -0,0 +1,23 @@
package com.tommasoberlose.anotherwidget.network.repository
import com.tommasoberlose.anotherwidget.network.api.WeatherGovApiService
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class WeatherGovRepository() {
private val apiService: WeatherGovApiService = getRetrofit().create(WeatherGovApiService::class.java)
suspend fun getGridPoints(latitude: String, longitude: String) = apiService.getGridPoints(latitude, longitude)
suspend fun getWeather(gridId: String, gridX: Double, gridY: Double) = apiService.getWeather(gridId, gridX.toInt(), gridY.toInt())
companion object {
private const val BASE_URL = "https://api.weather.gov/"
private fun getRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
}

View File

@ -102,6 +102,12 @@ class WeatherTabFragment : Fragment() {
checkLocationPermission()
})
viewModel.weatherProvider.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
label_weather_provider.text = WeatherHelper.getProviderName(requireContext(), Constants.WeatherProvider.fromInt(it)!!)
}
})
viewModel.weatherProviderApi.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
checkWeatherProviderConfig()
@ -198,6 +204,21 @@ class WeatherTabFragment : Fragment() {
Preferences.showWeather = enabled
}
action_weather_provider.setOnClickListener {
if (Preferences.showWeather) {
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_weather_provider_api)).setSelectedValue(Preferences.weatherProvider)
(0 until 11).forEach {
val item = Constants.WeatherProvider.fromInt(it)
dialog.addItem(WeatherHelper.getProviderName(requireContext(), item!!), it)
}
dialog.addOnSelectItemListener { value ->
Preferences.weatherProvider = value
checkWeatherProviderConfig()
}.show()
}
}
action_weather_provider_api_key.setOnClickListener {
if (Preferences.showWeather) {
startActivityForResult(

View File

@ -67,6 +67,7 @@ class MainViewModel : ViewModel() {
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
val weatherIconPack = Preferences.asLiveData(Preferences::weatherIconPack)
val weatherProvider = Preferences.asLiveData(Preferences::weatherProvider)
// Glance
val showGlance = Preferences.asLiveData(Preferences::showGlance)

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M13,13L13,13c-0.56,0.56 -1.45,0.56 -2,0.01L11,13c-0.55,-0.55 -0.55,-1.44 0,-1.99L11,11c0.55,-0.55 1.44,-0.55 1.99,0L13,11C13.55,11.55 13.55,12.45 13,13zM12,6l2.12,2.12l2.5,-2.5l-3.2,-3.2c-0.78,-0.78 -2.05,-0.78 -2.83,0l-3.2,3.2l2.5,2.5L12,6zM6,12l2.12,-2.12l-2.5,-2.5l-3.2,3.2c-0.78,0.78 -0.78,2.05 0,2.83l3.2,3.2l2.5,-2.5L6,12zM18,12l-2.12,2.12l2.5,2.5l3.2,-3.2c0.78,-0.78 0.78,-2.05 0,-2.83l-3.2,-3.2l-2.5,2.5L18,12zM12,18l-2.12,-2.12l-2.5,2.5l3.2,3.2c0.78,0.78 2.05,0.78 2.83,0l3.2,-3.2l-2.5,-2.5L12,18z"/>
</vector>

View File

@ -124,6 +124,44 @@
android:textColor="@color/colorAccent"
android:textAppearance="@style/AnotherWidget.Settings.Header"
app:textAllCaps="false" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_weather_provider"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_api"
app:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_weather_provider_api"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/label_weather_provider"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -114,6 +114,7 @@
<string name="settings_weather_icon_pack_title">Icon pack</string>
<string name="settings_weather_icon_pack_default">Icon pack %d</string>
<string name="background_location_warning">Raccoglieremo i dati sulla posizione per attivare l\'aggiornamento del meteo anche quando l\'app è chiusa o non in uso.\nNon utilizzeremo i tuoi dati in nessun altro modo.</string>
<string name="settings_weather_provider_api">Provider meteo</string>
<!-- Clock -->
<string name="settings_clock_title">Orologio</string>
@ -196,6 +197,8 @@
<string name="provider_header">Setup</string>
<string name="appearance_header">Stile</string>
<string name="preferences_header">Preferenze</string>
<string name="settings_privacy_policy_title"><![CDATA[Legal & Privacy]]></string>
<string name="settings_privacy_policy_subtitle">Apri la privacy policy dell\'app</string>
<!-- Activities -->
<string name="action_choose_application">Scegli applicazione</string>

View File

@ -118,6 +118,18 @@
<string name="settings_weather_icon_pack_title">Icon pack</string>
<string name="settings_weather_icon_pack_default">Icon pack %d</string>
<string name="background_location_warning">We will collect location data to update the weather information even when the app is closed or not in use.\nWe will not use these data otherwise.</string>
<string name="settings_weather_provider_api">Weather provider</string>
<string name="settings_weather_provider_open_weather">Open Weather Map</string>
<string name="settings_weather_provider_weatherbit">Weatherbit.io</string>
<string name="settings_weather_provider_foreca">Foreca.com</string>
<string name="settings_weather_provider_here">Here.com</string>
<string name="settings_weather_provider_accuweather">Accuweather.com</string>
<string name="settings_weather_provider_weather_gov">Weather.gov (US)\nPowered by National Weather Services</string>
<string name="settings_weather_provider_yr">YR.no/Met.no\nPowered by Meteorological Institute</string>
<string name="settings_weather_provider_smhi">Smhi.se (Swedish)\nPowered by Swedish Meteorological</string>
<string name="settings_weather_provider_weather_ca">Weather.gc.ca (Canada)</string>
<string name="settings_weather_provider_bom">BOM (Australia)\nPowered by Australia\'s national weather</string>
<string name="settings_weather_provider_meteofrance">Meteofrance.com (France)</string>
<!-- Clock -->
<string name="settings_clock_title">Clock</string>
@ -202,6 +214,8 @@
<string name="provider_header">Provider</string>
<string name="appearance_header">Appearance</string>
<string name="preferences_header">Preferences</string>
<string name="settings_privacy_policy_title"><![CDATA[Legal & Privacy]]></string>
<string name="settings_privacy_policy_subtitle">View the privacy policy of the app</string>
<!-- Activities -->
<string name="action_choose_application">Choose application</string>
@ -217,6 +231,4 @@
<string name="settings_title_integrations">Integrations</string>
<string name="label_count_installed_integrations">%d installed integrations</string>
<string name="nothing">Nothing</string>
<string name="settings_privacy_policy_title"><![CDATA[Legal & Privacy]]></string>
<string name="settings_privacy_policy_subtitle">View the privacy policy of the app</string>
</resources>