diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4434b5da6ab7e16ce02d0e70c018ade234e7f9c7..0bea12eddd934d3e656a276e5c9c8b1b14ebaf07 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,3 +19,5 @@ build:
artifacts:
paths:
- app/build/outputs/apk
+ before_script:
+ - sed -i 's/DEFAULT_OWM_KEY/'${DEFAULT_OWM_KEY}'/g' app/src/main/res/values/strings.xml
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/Preferences.java b/app/src/main/java/foundation/e/blisslauncher/core/Preferences.java
index 91c17ebece0937c397bcf419db5acfc742fc5c6b..859b4892fc171b7d744f5c7073b1a527405158db 100644
--- a/app/src/main/java/foundation/e/blisslauncher/core/Preferences.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/Preferences.java
@@ -236,6 +236,16 @@ public class Preferences {
editor.apply();
}
+ public static void setCachedCity(Context context, String city) {
+ SharedPreferences.Editor editor = getPrefs(context).edit();
+ editor.putString(Constants.CACHED_CITY, city);
+ editor.apply();
+ }
+
+ public static String getCachedCity(Context context) {
+ return getPrefs(context).getString(Constants.CACHED_CITY, "Unknown");
+ }
+
public static long lastWeatherUpdateTimestamp(Context context) {
return getPrefs(context).getLong(Constants.WEATHER_LAST_UPDATE, 0);
}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/utils/Constants.java b/app/src/main/java/foundation/e/blisslauncher/core/utils/Constants.java
index c0f06554091206724a099972697f20e19f52fd9e..a308315abe1e829e12ef4aabeacff82e5aec2e77 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/utils/Constants.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/utils/Constants.java
@@ -39,6 +39,8 @@ public class Constants {
public static final String FORCE_WEATHER_LAST_TRY = "last_weather_try";
public static final String WEATHER_DATA = "weather_data";
+ public static final String CACHED_CITY = "cached_city";
+
// First run is used to hide the initial no-weather message for a better OOBE
public static final String WEATHER_FIRST_UPDATE = "weather_first_update";
diff --git a/app/src/main/java/foundation/e/blisslauncher/features/weather/ForecastBuilder.java b/app/src/main/java/foundation/e/blisslauncher/features/weather/ForecastBuilder.java
index c37064061f736ebea3bf1af5a7c5278934ffdfbc..f0ba009b9d590d417a303c118ddc5fd60cac4be3 100644
--- a/app/src/main/java/foundation/e/blisslauncher/features/weather/ForecastBuilder.java
+++ b/app/src/main/java/foundation/e/blisslauncher/features/weather/ForecastBuilder.java
@@ -72,8 +72,8 @@ public class ForecastBuilder {
w.getConditionCode(), WeatherIconUtils.getNextHigherDensity(context)));
// City
- TextView city = weatherPanel.findViewById(R.id.weather_city);
- city.setText(w.getCity());
+ TextView textCity = weatherPanel.findViewById(R.id.weather_city);
+ textCity.setText(Preferences.getCachedCity(context));
// Weather Condition
TextView weatherCondition = weatherPanel.findViewById(R.id.weather_condition);
diff --git a/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherInfoView.java b/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherInfoView.java
index a28add39efccc4f7489deda9e9065c226a4ae32c..2fd655ffe9c666dccaa73fa8272c09df0591cf8f 100644
--- a/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherInfoView.java
+++ b/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherInfoView.java
@@ -8,6 +8,8 @@ import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
+import android.widget.TextView;
+
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import foundation.e.blisslauncher.R;
import foundation.e.blisslauncher.core.Preferences;
@@ -25,8 +27,17 @@ public class WeatherInfoView extends LinearLayout {
if (WeatherUpdateService.ACTION_UPDATE_FINISHED.equals(intent.getAction())) {
updateWeatherPanel();
}
+
+ if (WeatherUpdateService.ACTION_UPDATE_CITY_FINISHED.equals(intent.getAction())) {
+ final TextView textCity = mWeatherPanel.findViewById(R.id.weather_city);
+ final String city = intent.getStringExtra(WeatherUpdateService.EXTRA_UPDATE_CITY_KEY);
+ if (city != null && !city.trim().isEmpty()) {
+ textCity.setText(city);
+ }
+ }
}
};
+
private final BroadcastReceiver mResumeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -61,8 +72,12 @@ public class WeatherInfoView extends LinearLayout {
protected void onAttachedToWindow() {
super.onAttachedToWindow();
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext());
- broadcastManager.registerReceiver(mWeatherReceiver,
- new IntentFilter(WeatherUpdateService.ACTION_UPDATE_FINISHED));
+ final IntentFilter intentFilter = new IntentFilter();
+
+ intentFilter.addAction(WeatherUpdateService.ACTION_UPDATE_FINISHED);
+ intentFilter.addAction(WeatherUpdateService.ACTION_UPDATE_CITY_FINISHED);
+
+ broadcastManager.registerReceiver(mWeatherReceiver, intentFilter);
broadcastManager.registerReceiver(mResumeReceiver, new IntentFilter(LauncherActivity.ACTION_LAUNCHER_RESUME));
updateWeatherPanel();
}
diff --git a/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdateService.java b/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdateService.java
index 77d98496e9e8c9a0d854629e46ffc3fe5d3b10a3..d7be85fdf0155b6f3963a7ceaf9bc70772b1a782 100644
--- a/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdateService.java
+++ b/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdateService.java
@@ -15,6 +15,8 @@ public class WeatherUpdateService extends Service {
public static final String ACTION_FORCE_UPDATE = "org.indin.blisslauncher.action.FORCE_WEATHER_UPDATE";
public static final String ACTION_UPDATE_FINISHED = "org.indin.blisslauncher.action.WEATHER_UPDATE_FINISHED";
+ public static final String ACTION_UPDATE_CITY_FINISHED = "org.indin.blisslauncher.action.WEATHER_UPDATE_CITY_FINISHED";
+ public static final String EXTRA_UPDATE_CITY_KEY = "city";
private static final long UPDATE_PERIOD_IN_MS = 5L * 1000L;
diff --git a/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdater.java b/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdater.java
index 303aac6ae2b76067b46d64d30a719200b36be523..caa76ee31fec00d9a8d3f473586d1407557970bb 100644
--- a/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdater.java
+++ b/app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdater.java
@@ -16,13 +16,27 @@ import androidx.core.app.ActivityCompat;
import androidx.core.location.LocationManagerCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+
+import java.io.IOException;
import java.lang.ref.WeakReference;
+import java.util.Locale;
import java.util.concurrent.Executors;
+import foundation.e.blisslauncher.R;
import foundation.e.blisslauncher.core.Preferences;
import lineageos.weather.LineageWeatherManager;
import lineageos.weather.WeatherInfo;
import lineageos.weather.WeatherLocation;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
public class WeatherUpdater {
@@ -153,6 +167,10 @@ public class WeatherUpdater {
}
requestWeatherUpdate(getMostRecentLocation());
+
+ if (!Preferences.useCustomWeatherLocation(mWeakContext.get())) {
+ reverseGeocodeLocation(getMostRecentLocation());
+ }
}
private void notifyUi(@NonNull Context context, @Nullable WeatherInfo weatherInfo, int status) {
@@ -163,6 +181,7 @@ public class WeatherUpdater {
}
Log.i(TAG, "WeatherInfo=" + weatherInfo);
+
long now = SystemClock.elapsedRealtime();
Preferences.setCachedWeatherInfo(context, now, weatherInfo);
Preferences.setLastWeatherUpdateTimestamp(context, now);
@@ -188,4 +207,66 @@ public class WeatherUpdater {
long networkTime = mNetworkLocation.getTime();
return gpsTime >= networkTime ? mGpsLocation : mNetworkLocation;
}
+
+ private void reverseGeocodeLocation(@NonNull Location location) {
+ Log.i(TAG, "Reverse geocoding location " + location);
+
+ final String url = "https://api.openweathermap.org/geo/1.0/reverse?lat=" + location.getLatitude() + "&lon="
+ + location.getLongitude() + "&limit=1&appid=" + mWeakContext.get().getString(R.string.default_key);
+
+ final OkHttpClient okHttpClient = new OkHttpClient();
+ final Request request = new Request.Builder().url(url).build();
+ okHttpClient.newCall(request).enqueue(mReverseGeocodeCallback);
+ }
+
+ private void onReverseGeocoded(@NonNull Response response) {
+ final ResponseBody body = response.body();
+ if (body == null) {
+ Log.w(TAG, "Reverse geocoding response is empty");
+ return;
+ }
+
+ JsonObject locales;
+ try {
+ final String json = body.string();
+ final JsonArray array = new JsonParser().parse(json).getAsJsonArray();
+ locales = array.get(0).getAsJsonObject().getAsJsonObject("local_names");
+ } catch (IOException | IllegalStateException | JsonSyntaxException exception) {
+ Log.e(TAG, "Exception caught", exception);
+ return;
+ }
+
+ if (locales == null) {
+ Log.e(TAG, "Could not get locales");
+ return;
+ }
+
+ String countryCode = Locale.getDefault().getCountry().toLowerCase(Locale.ROOT);
+ if (!locales.has(countryCode)) {
+ countryCode = locales.get("en").getAsString();
+ }
+
+ final String city = locales.get(countryCode).getAsString();
+ notifyUi(city);
+ }
+
+ private void notifyUi(@NonNull String city) {
+ Context context = mWeakContext.get();
+ Preferences.setCachedCity(context, city);
+ final Intent intent = new Intent(WeatherUpdateService.ACTION_UPDATE_CITY_FINISHED);
+ intent.putExtra(WeatherUpdateService.EXTRA_UPDATE_CITY_KEY, city);
+ LocalBroadcastManager.getInstance(mWeakContext.get()).sendBroadcast(intent);
+ }
+
+ private final Callback mReverseGeocodeCallback = new Callback() {
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull IOException e) {
+ Log.e(TAG, "Could not reverse geocode location", e);
+ }
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
+ onReverseGeocoded(response);
+ }
+ };
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 01ff014d6d00efae037782047c9cdc40e07994f6..7b5c62ab4a9de89f5bf336f0227453e626377e64 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,6 +9,8 @@
Unknown
Cancel
+ DEFAULT_OWM_KEY
+
Tornado
Tropical Storm