diff options
Diffstat (limited to 'src/com/cyanogenmod/lockclock/misc/Preferences.java')
-rw-r--r-- | src/com/cyanogenmod/lockclock/misc/Preferences.java | 262 |
1 files changed, 231 insertions, 31 deletions
diff --git a/src/com/cyanogenmod/lockclock/misc/Preferences.java b/src/com/cyanogenmod/lockclock/misc/Preferences.java index 941e761..0e1062e 100644 --- a/src/com/cyanogenmod/lockclock/misc/Preferences.java +++ b/src/com/cyanogenmod/lockclock/misc/Preferences.java @@ -19,17 +19,44 @@ package com.cyanogenmod.lockclock.misc; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Color; - -import com.cyanogenmod.lockclock.weather.OpenWeatherMapProvider; -import com.cyanogenmod.lockclock.weather.WeatherInfo; -import com.cyanogenmod.lockclock.weather.WeatherProvider; -import com.cyanogenmod.lockclock.weather.YahooWeatherProvider; - +import com.cyanogenmod.lockclock.weather.Utils; +import cyanogenmod.weather.WeatherInfo; +import cyanogenmod.weather.WeatherLocation; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; import java.util.Set; public class Preferences { + + private static final String WEATHER_LOCATION_CITY_ID = "city_id"; + private static final String WEATHER_LOCATION_CITY_NAME = "city_name"; + private static final String WEATHER_LOCATION_STATE = "state"; + private static final String WEATHER_LOCATION_POSTAL_CODE = "postal_code"; + private static final String WEATHER_LOCATION_COUNTRY_ID = "country_id"; + private static final String WEATHER_LOCATION_COUNTRY_NAME = "country_name"; + + private static final String WEATHER_INFO_CITY = "city"; + private static final String WEATHER_INFO_CONDITION_CODE = "condition_code"; + private static final String WEATHER_INFO_TEMPERATURE = "temperature"; + private static final String WEATHER_INFO_TEMPERATURE_UNIT = "temperature_unit"; + private static final String WEATHER_INFO_TIMESTAMP = "timestamp"; + private static final String WEATHER_INFO_HUMIDITY = "humidity"; + private static final String WEATHER_INFO_TODAYS_HIGH = "todays_high"; + private static final String WEATHER_INFO_TODAYS_LOW = "todays_low"; + private static final String WEATHER_INFO_WIND_SPEED = "wind_speed"; + private static final String WEATHER_INFO_WIND_SPEED_UNIT = "wind_speed_unit"; + private static final String WEATHER_INFO_WIND_SPEED_DIRECTION = "wind_speed_direction"; + private static final String WEATHER_INFO_FORECAST = "forecasts"; + + private static final String DAY_FORECAST_CONDITION_CODE = "condition_code"; + private static final String DAY_FORECAST_LOW = "low"; + private static final String DAY_FORECAST_HIGH = "high"; + private Preferences() { } @@ -46,7 +73,8 @@ public class Preferences { } public static boolean showWeather(Context context) { - return getPrefs(context).getBoolean(Constants.SHOW_WEATHER, true); + return getPrefs(context).getBoolean(Constants.SHOW_WEATHER, true) + && Utils.isWeatherServiceAvailable(context); } public static boolean showCalendar(Context context) { @@ -172,7 +200,7 @@ public class Preferences { public static long weatherRefreshIntervalInMs(Context context) { String value = getPrefs(context).getString(Constants.WEATHER_REFRESH_INTERVAL, "60"); - return Long.parseLong(value) * 60 * 1000; + return Long.parseLong(value) * 60L * 1000L; } public static boolean useCustomWeatherLocation(Context context) { @@ -183,37 +211,148 @@ public class Preferences { getPrefs(context).edit().putBoolean(Constants.WEATHER_USE_CUSTOM_LOCATION, value).apply(); } - public static String customWeatherLocationId(Context context) { - return getPrefs(context).getString(Constants.WEATHER_CUSTOM_LOCATION_ID, null); + public static String getCustomWeatherLocationCity(Context context) { + return getPrefs(context).getString(Constants.WEATHER_CUSTOM_LOCATION_CITY, null); } - public static void setCustomWeatherLocationId(Context context, String id) { - getPrefs(context).edit().putString(Constants.WEATHER_CUSTOM_LOCATION_ID, id).apply(); + public static void setCustomWeatherLocationCity(Context context, String city) { + getPrefs(context).edit().putString(Constants.WEATHER_CUSTOM_LOCATION_CITY, city).apply(); } - public static String customWeatherLocationCity(Context context) { - return getPrefs(context).getString(Constants.WEATHER_CUSTOM_LOCATION_CITY, null); + public static boolean setCustomWeatherLocation(Context context, WeatherLocation weatherLocation) { + if (weatherLocation == null) { + getPrefs(context).edit() + .remove(Constants.WEATHER_CUSTOM_LOCATION).apply(); + return true; + } + try { + JSONObject jsonObject = weatherLocationToJSON(weatherLocation); + getPrefs(context).edit() + .putString(Constants.WEATHER_CUSTOM_LOCATION, jsonObject.toString()).apply(); + return true; + } catch (JSONException e) { + // We're here because weatherLocationToJSON() or jsonObject.toString() failed. + // Either way, it means the pref was not updated + return false; + } } - public static void setCustomWeatherLocationCity(Context context, String city) { - getPrefs(context).edit().putString(Constants.WEATHER_CUSTOM_LOCATION_CITY, city).apply(); + public static WeatherLocation getCustomWeatherLocation(Context context) { + String weatherLocation = getPrefs(context) + .getString(Constants.WEATHER_CUSTOM_LOCATION, null); + + if (weatherLocation == null) { + return null; + } + + try { + JSONObject jsonObject = new JSONObject(weatherLocation); + return JSONToWeatherLocation(jsonObject); + } catch (JSONException e) { + return null; + } } - public static WeatherProvider weatherProvider(Context context) { - String name = getPrefs(context).getString(Constants.WEATHER_SOURCE, "yahoo"); - if (name.equals("openweathermap")) { - return new OpenWeatherMapProvider(context); + private static WeatherLocation JSONToWeatherLocation(JSONObject jsonObject) + throws JSONException { + String cityId; + String cityName; + String state; + String postalCode; + String countryId; + String countryName; + + cityId = jsonObject.getString(WEATHER_LOCATION_CITY_ID); + cityName = jsonObject.getString(WEATHER_LOCATION_CITY_NAME); + state = jsonObject.getString(WEATHER_LOCATION_STATE); + postalCode = jsonObject.getString(WEATHER_LOCATION_POSTAL_CODE); + countryId = jsonObject.getString(WEATHER_LOCATION_COUNTRY_ID); + countryName = jsonObject.getString(WEATHER_LOCATION_COUNTRY_NAME); + + //We need at least city id and city name to build a WeatherLocation + if (cityId == null && cityName == null) { + return null; } - return new YahooWeatherProvider(context); + + WeatherLocation.Builder location = new WeatherLocation.Builder(cityId, cityName); + if (countryId != null) location.setCountryId(countryId); + if (countryName != null) location.setCountry(countryName); + if (state != null) location.setState(state); + if (postalCode != null) location.setPostalCode(postalCode); + + return location.build(); } - public static void setCachedWeatherInfo(Context context, long timestamp, WeatherInfo data) { + private static JSONObject weatherLocationToJSON(WeatherLocation location) throws JSONException { + return new JSONObject() + .put(WEATHER_LOCATION_CITY_ID, location.getCityId()) + .put(WEATHER_LOCATION_CITY_NAME, location.getCity()) + .put(WEATHER_LOCATION_STATE, location.getState()) + .put(WEATHER_LOCATION_POSTAL_CODE, location.getPostalCode()) + .put(WEATHER_LOCATION_COUNTRY_ID, location.getCountryId()) + .put(WEATHER_LOCATION_COUNTRY_NAME, location.getCountry()); + } + + public static void setCachedWeatherInfo(Context context, long timestamp, WeatherInfo info) { SharedPreferences.Editor editor = getPrefs(context).edit(); editor.putLong(Constants.WEATHER_LAST_UPDATE, timestamp); - if (data != null) { + if (info != null) { // We now have valid weather data to display - editor.putBoolean(Constants.WEATHER_FIRST_UPDATE, false); - editor.putString(Constants.WEATHER_DATA, data.toSerializedString()); + JSONObject jsonObject = new JSONObject(); + boolean serialized = false; + try { + //These members always return a value that can be parsed + jsonObject + .put(WEATHER_INFO_CITY, info.getCity()) + .put(WEATHER_INFO_CONDITION_CODE, info.getConditionCode()) + .put(WEATHER_INFO_TEMPERATURE, info.getTemperature()) + .put(WEATHER_INFO_TEMPERATURE_UNIT, info.getTemperatureUnit()) + .put(WEATHER_INFO_TIMESTAMP, info.getTimestamp()); + + // Handle special cases. JSONObject.put(key, double) does not allow + // Double.NaN, so we store it as a string. JSONObject.getDouble() will parse the + // "NaN" string and return Double.NaN, which is what we want + double humidity = info.getHumidity(); + jsonObject.put(WEATHER_INFO_HUMIDITY, Double.isNaN(humidity) ? "NaN" : humidity); + + double todaysHigh = info.getTodaysHigh(); + jsonObject.put(WEATHER_INFO_TODAYS_HIGH, Double.isNaN(todaysHigh) + ? "NaN" : todaysHigh); + + double todaysLow = info.getTodaysLow(); + jsonObject.put(WEATHER_INFO_TODAYS_LOW, Double.isNaN(todaysLow) + ? "NaN" : todaysLow); + + double windSpeed = info.getWindSpeed(); + double windDirection = info.getWindDirection(); + jsonObject.put(WEATHER_INFO_WIND_SPEED, Double.isNaN(windSpeed) ? "NaN" : windSpeed) + .put(WEATHER_INFO_WIND_SPEED_UNIT, info.getWindSpeedUnit()) + .put(WEATHER_INFO_WIND_SPEED_DIRECTION, Double.isNaN(windDirection) + ? "NaN" : windDirection); + + JSONArray forecastArray = new JSONArray(); + for (WeatherInfo.DayForecast forecast : info.getForecasts()) { + JSONObject jsonForecast = new JSONObject() + .put(DAY_FORECAST_CONDITION_CODE, forecast.getConditionCode()); + + double low = forecast.getLow(); + jsonForecast.put(DAY_FORECAST_LOW, Double.isNaN(low) ? "NaN" : low); + double high = forecast.getHigh(); + jsonForecast.put(DAY_FORECAST_HIGH, Double.isNaN(high) ? "NaN" : high); + forecastArray.put(jsonForecast); + } + jsonObject.put(WEATHER_INFO_FORECAST, forecastArray); + serialized = true; + } catch (JSONException e) { + // We're here because something went wrong while creating the JSON object. + // The code below will check for success and proceed accordingly + } + if (serialized) { + editor.putString(Constants.WEATHER_DATA, jsonObject.toString()); + editor.putBoolean(Constants.WEATHER_FIRST_UPDATE, false); + } + } else { + editor.remove(Constants.WEATHER_DATA); } editor.apply(); } @@ -222,17 +361,78 @@ public class Preferences { return getPrefs(context).getLong(Constants.WEATHER_LAST_UPDATE, 0); } + public static void setLastWeatherUpadteTimestamp(Context context, long timestamp) { + getPrefs(context).edit().putLong(Constants.WEATHER_LAST_UPDATE, timestamp).apply(); + } + public static WeatherInfo getCachedWeatherInfo(Context context) { - return WeatherInfo.fromSerializedString(context, - getPrefs(context).getString(Constants.WEATHER_DATA, null)); + final String cachedInfo = getPrefs(context).getString(Constants.WEATHER_DATA, null); + + if (cachedInfo == null) return null; + + String city; + int conditionCode; + double temperature; + int tempUnit; + double humidity; + double windSpeed; + double windDirection; + double todaysHigh; + double todaysLow; + int windSpeedUnit; + long timestamp; + ArrayList<WeatherInfo.DayForecast> forecastList = new ArrayList<>(); + + try { + JSONObject cached = new JSONObject(cachedInfo); + city = cached.getString(WEATHER_INFO_CITY); + conditionCode = cached.getInt(WEATHER_INFO_CONDITION_CODE); + temperature = cached.getDouble(WEATHER_INFO_TEMPERATURE); + tempUnit = cached.getInt(WEATHER_INFO_TEMPERATURE_UNIT); + humidity = cached.getDouble(WEATHER_INFO_HUMIDITY); + windSpeed = cached.getDouble(WEATHER_INFO_WIND_SPEED); + windDirection = cached.getDouble(WEATHER_INFO_WIND_SPEED_DIRECTION); + windSpeedUnit = cached.getInt(WEATHER_INFO_WIND_SPEED_UNIT); + timestamp = cached.getLong(WEATHER_INFO_TIMESTAMP); + todaysHigh = cached.getDouble(WEATHER_INFO_TODAYS_HIGH); + todaysLow = cached.getDouble(WEATHER_INFO_TODAYS_LOW); + JSONArray forecasts = cached.getJSONArray(WEATHER_INFO_FORECAST); + for (int indx = 0; indx < forecasts.length(); indx++) { + JSONObject forecast = forecasts.getJSONObject(indx); + double low; + double high; + int code; + low = forecast.getDouble(DAY_FORECAST_LOW); + high = forecast.getDouble(DAY_FORECAST_HIGH); + code = forecast.getInt(DAY_FORECAST_CONDITION_CODE); + WeatherInfo.DayForecast.Builder f = new WeatherInfo.DayForecast.Builder(code); + if (!Double.isNaN(low)) f.setLow(low); + if (!Double.isNaN(high)) f.setHigh(high); + forecastList.add(f.build()); + } + WeatherInfo.Builder weatherInfo = new WeatherInfo.Builder(city, temperature, tempUnit) + .setWeatherCondition(conditionCode) + .setTimestamp(timestamp); + + if (!Double.isNaN(humidity)) weatherInfo.setHumidity(humidity); + if (!Double.isNaN(windSpeed) && !Double.isNaN(windDirection)) { + weatherInfo.setWind(windSpeed, windDirection, windSpeedUnit); + } + if (forecastList.size() > 0) weatherInfo.setForecast(forecastList); + if (!Double.isNaN(todaysHigh)) weatherInfo.setTodaysHigh(todaysHigh); + if (!Double.isNaN(todaysLow)) weatherInfo.setTodaysLow(todaysLow); + return weatherInfo.build(); + } catch (JSONException e) { + } + return null; } - public static String getCachedLocationId(Context context) { - return getPrefs(context).getString(Constants.WEATHER_LOCATION_ID, null); + public static void setWeatherSource(Context context, String source) { + getPrefs(context).edit().putString(Constants.WEATHER_SOURCE, source).apply(); } - public static void setCachedLocationId(Context context, String id) { - getPrefs(context).edit().putString(Constants.WEATHER_LOCATION_ID, id).apply(); + public static String getWeatherSource(Context context) { + return getPrefs(context).getString(Constants.WEATHER_SOURCE, null); } public static Set<String> calendarsToDisplay(Context context) { |