Skip to content

Commit b7cef09

Browse files
committed
Reverse geocode location to be more accurate
1 parent c7d78ae commit b7cef09

File tree

8 files changed

+118
-4
lines changed

8 files changed

+118
-4
lines changed

.gitlab-ci.yml

+2
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ build:
1919
artifacts:
2020
paths:
2121
- app/build/outputs/apk
22+
before_script:
23+
- sed -i 's/DEFAULT_OWM_KEY/'${DEFAULT_OWM_KEY}'/g' app/src/main/res/values/strings.xml

app/src/main/java/foundation/e/blisslauncher/core/Preferences.java

+10
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,16 @@ public static void setCachedWeatherInfo(Context context, long timestamp, Weather
236236
editor.apply();
237237
}
238238

239+
public static void setCachedCity(Context context, String city) {
240+
SharedPreferences.Editor editor = getPrefs(context).edit();
241+
editor.putString(Constants.CACHED_CITY, city);
242+
editor.apply();
243+
}
244+
245+
public static String getCachedCity(Context context) {
246+
return getPrefs(context).getString(Constants.CACHED_CITY, "Unknown");
247+
}
248+
239249
public static long lastWeatherUpdateTimestamp(Context context) {
240250
return getPrefs(context).getLong(Constants.WEATHER_LAST_UPDATE, 0);
241251
}

app/src/main/java/foundation/e/blisslauncher/core/utils/Constants.java

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public class Constants {
3939
public static final String FORCE_WEATHER_LAST_TRY = "last_weather_try";
4040
public static final String WEATHER_DATA = "weather_data";
4141

42+
public static final String CACHED_CITY = "cached_city";
43+
4244
// First run is used to hide the initial no-weather message for a better OOBE
4345
public static final String WEATHER_FIRST_UPDATE = "weather_first_update";
4446

app/src/main/java/foundation/e/blisslauncher/features/weather/ForecastBuilder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ public static void buildLargePanel(Context context, View weatherPanel, WeatherIn
7272
w.getConditionCode(), WeatherIconUtils.getNextHigherDensity(context)));
7373

7474
// City
75-
TextView city = weatherPanel.findViewById(R.id.weather_city);
76-
city.setText(w.getCity());
75+
TextView textCity = weatherPanel.findViewById(R.id.weather_city);
76+
textCity.setText(Preferences.getCachedCity(context));
7777

7878
// Weather Condition
7979
TextView weatherCondition = weatherPanel.findViewById(R.id.weather_condition);

app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherInfoView.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import android.util.Log;
99
import android.view.View;
1010
import android.widget.LinearLayout;
11+
import android.widget.TextView;
12+
1113
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
1214
import foundation.e.blisslauncher.R;
1315
import foundation.e.blisslauncher.core.Preferences;
@@ -25,8 +27,17 @@ public void onReceive(Context context, Intent intent) {
2527
if (WeatherUpdateService.ACTION_UPDATE_FINISHED.equals(intent.getAction())) {
2628
updateWeatherPanel();
2729
}
30+
31+
if (WeatherUpdateService.ACTION_UPDATE_CITY_FINISHED.equals(intent.getAction())) {
32+
final TextView textCity = mWeatherPanel.findViewById(R.id.weather_city);
33+
final String city = intent.getStringExtra(WeatherUpdateService.EXTRA_UPDATE_CITY_KEY);
34+
if (city != null && !city.trim().isEmpty()) {
35+
textCity.setText(city);
36+
}
37+
}
2838
}
2939
};
40+
3041
private final BroadcastReceiver mResumeReceiver = new BroadcastReceiver() {
3142
@Override
3243
public void onReceive(Context context, Intent intent) {
@@ -61,8 +72,12 @@ protected void onFinishInflate() {
6172
protected void onAttachedToWindow() {
6273
super.onAttachedToWindow();
6374
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext());
64-
broadcastManager.registerReceiver(mWeatherReceiver,
65-
new IntentFilter(WeatherUpdateService.ACTION_UPDATE_FINISHED));
75+
final IntentFilter intentFilter = new IntentFilter();
76+
77+
intentFilter.addAction(WeatherUpdateService.ACTION_UPDATE_FINISHED);
78+
intentFilter.addAction(WeatherUpdateService.ACTION_UPDATE_CITY_FINISHED);
79+
80+
broadcastManager.registerReceiver(mWeatherReceiver, intentFilter);
6681
broadcastManager.registerReceiver(mResumeReceiver, new IntentFilter(LauncherActivity.ACTION_LAUNCHER_RESUME));
6782
updateWeatherPanel();
6883
}

app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdateService.java

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public class WeatherUpdateService extends Service {
1515

1616
public static final String ACTION_FORCE_UPDATE = "org.indin.blisslauncher.action.FORCE_WEATHER_UPDATE";
1717
public static final String ACTION_UPDATE_FINISHED = "org.indin.blisslauncher.action.WEATHER_UPDATE_FINISHED";
18+
public static final String ACTION_UPDATE_CITY_FINISHED = "org.indin.blisslauncher.action.WEATHER_UPDATE_CITY_FINISHED";
19+
public static final String EXTRA_UPDATE_CITY_KEY = "city";
1820

1921
private static final long UPDATE_PERIOD_IN_MS = 5L * 1000L;
2022

app/src/main/java/foundation/e/blisslauncher/features/weather/WeatherUpdater.java

+81
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,27 @@
1616
import androidx.core.location.LocationManagerCompat;
1717
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
1818

19+
import com.google.gson.JsonArray;
20+
import com.google.gson.JsonObject;
21+
import com.google.gson.JsonParser;
22+
import com.google.gson.JsonSyntaxException;
23+
24+
import java.io.IOException;
1925
import java.lang.ref.WeakReference;
26+
import java.util.Locale;
2027
import java.util.concurrent.Executors;
2128

29+
import foundation.e.blisslauncher.R;
2230
import foundation.e.blisslauncher.core.Preferences;
2331
import lineageos.weather.LineageWeatherManager;
2432
import lineageos.weather.WeatherInfo;
2533
import lineageos.weather.WeatherLocation;
34+
import okhttp3.Call;
35+
import okhttp3.Callback;
36+
import okhttp3.OkHttpClient;
37+
import okhttp3.Request;
38+
import okhttp3.Response;
39+
import okhttp3.ResponseBody;
2640

2741
public class WeatherUpdater {
2842

@@ -153,6 +167,10 @@ private synchronized void onNewLocationFetched(@Nullable Location location) {
153167
}
154168

155169
requestWeatherUpdate(getMostRecentLocation());
170+
171+
if (!Preferences.useCustomWeatherLocation(mWeakContext.get())) {
172+
reverseGeocodeLocation(getMostRecentLocation());
173+
}
156174
}
157175

158176
private void notifyUi(@NonNull Context context, @Nullable WeatherInfo weatherInfo, int status) {
@@ -163,6 +181,7 @@ private void notifyUi(@NonNull Context context, @Nullable WeatherInfo weatherInf
163181
}
164182

165183
Log.i(TAG, "WeatherInfo=" + weatherInfo);
184+
166185
long now = SystemClock.elapsedRealtime();
167186
Preferences.setCachedWeatherInfo(context, now, weatherInfo);
168187
Preferences.setLastWeatherUpdateTimestamp(context, now);
@@ -188,4 +207,66 @@ private Location getMostRecentLocation() {
188207
long networkTime = mNetworkLocation.getTime();
189208
return gpsTime >= networkTime ? mGpsLocation : mNetworkLocation;
190209
}
210+
211+
private void reverseGeocodeLocation(@NonNull Location location) {
212+
Log.i(TAG, "Reverse geocoding location " + location);
213+
214+
final String url = "https://api.openweathermap.org/geo/1.0/reverse?lat=" + location.getLatitude() + "&lon="
215+
+ location.getLongitude() + "&limit=1&appid=" + mWeakContext.get().getString(R.string.default_key);
216+
217+
final OkHttpClient okHttpClient = new OkHttpClient();
218+
final Request request = new Request.Builder().url(url).build();
219+
okHttpClient.newCall(request).enqueue(mReverseGeocodeCallback);
220+
}
221+
222+
private void onReverseGeocoded(@NonNull Response response) {
223+
final ResponseBody body = response.body();
224+
if (body == null) {
225+
Log.w(TAG, "Reverse geocoding response is empty");
226+
return;
227+
}
228+
229+
JsonObject locales;
230+
try {
231+
final String json = body.string();
232+
final JsonArray array = new JsonParser().parse(json).getAsJsonArray();
233+
locales = array.get(0).getAsJsonObject().getAsJsonObject("local_names");
234+
} catch (IOException | IllegalStateException | JsonSyntaxException exception) {
235+
Log.e(TAG, "Exception caught", exception);
236+
return;
237+
}
238+
239+
if (locales == null) {
240+
Log.e(TAG, "Could not get locales");
241+
return;
242+
}
243+
244+
String countryCode = Locale.getDefault().getCountry().toLowerCase(Locale.ROOT);
245+
if (!locales.has(countryCode)) {
246+
countryCode = locales.get("en").getAsString();
247+
}
248+
249+
final String city = locales.get(countryCode).getAsString();
250+
notifyUi(city);
251+
}
252+
253+
private void notifyUi(@NonNull String city) {
254+
Context context = mWeakContext.get();
255+
Preferences.setCachedCity(context, city);
256+
final Intent intent = new Intent(WeatherUpdateService.ACTION_UPDATE_CITY_FINISHED);
257+
intent.putExtra(WeatherUpdateService.EXTRA_UPDATE_CITY_KEY, city);
258+
LocalBroadcastManager.getInstance(mWeakContext.get()).sendBroadcast(intent);
259+
}
260+
261+
private final Callback mReverseGeocodeCallback = new Callback() {
262+
@Override
263+
public void onFailure(@NonNull Call call, @NonNull IOException e) {
264+
Log.e(TAG, "Could not reverse geocode location", e);
265+
}
266+
267+
@Override
268+
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
269+
onReverseGeocoded(response);
270+
}
271+
};
191272
}

app/src/main/res/values/strings.xml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
</string>
1010
<string name="unknown">Unknown</string>
1111
<string name="cancel">Cancel</string>
12+
<string name="default_key">DEFAULT_OWM_KEY</string>
13+
1214
<!-- Weather - Weather codes -->
1315
<string name="weather_0">Tornado</string>
1416
<string name="weather_1">Tropical Storm</string>

0 commit comments

Comments
 (0)