diff options
Diffstat (limited to 'src/com/cyanogenmod/lockclock/weather')
4 files changed, 533 insertions, 152 deletions
diff --git a/src/com/cyanogenmod/lockclock/weather/WeatherInfo.java b/src/com/cyanogenmod/lockclock/weather/WeatherInfo.java index bb4a5fa..420900d 100644 --- a/src/com/cyanogenmod/lockclock/weather/WeatherInfo.java +++ b/src/com/cyanogenmod/lockclock/weather/WeatherInfo.java @@ -17,99 +17,208 @@ package com.cyanogenmod.lockclock.weather; import android.content.Context; +import android.content.res.Resources; + import com.cyanogenmod.lockclock.R; +import com.cyanogenmod.lockclock.misc.Preferences; + +import java.text.DecimalFormat; +import java.util.Date; public class WeatherInfo { + private static final long serialVersionUID = 1L; - public static final String NODATA = "-"; - - public String city, forecast_date, condition, condition_code, temp, temp_unit, - humidity, wind, wind_dir, speed_unit, low, high; - public long last_sync; - - public WeatherInfo() { - this.city = NODATA; - this.forecast_date = NODATA; - this.condition = NODATA; - this.condition_code = NODATA; - this.temp = NODATA; - this.temp_unit = NODATA; - this.humidity = NODATA; - this.wind = NODATA; - this.wind_dir = NODATA; - this.speed_unit = NODATA; - this.low = NODATA; - this.high = NODATA; - this.last_sync = 0; - } + private static final DecimalFormat sNoDigitsFormat = new DecimalFormat("0"); - public WeatherInfo(Context context, String city, String fdate, String condition, String condition_code, - String temp, String temp_unit, String humidity, - String wind, String wind_dir, String speed_unit, - String low, String high, long last_sync) { + private Context mContext; + + private String city; + private String forecastDate; + private String condition; + private int conditionCode; + private float temperature; + private float lowTemperature; + private float highTemperature; + private String tempUnit; + private float humidity; + private float wind; + private int windDirection; + private String speedUnit; + private long timestamp; + + public WeatherInfo(Context context, + String city, String fdate, String condition, int conditionCode, + float temp, float low, float high, String tempUnit, float humidity, + float wind, int windDir, String speedUnit, long timestamp) { + this.mContext = context; this.city = city; - this.forecast_date = fdate; + this.forecastDate = fdate; this.condition = condition; - this.condition_code = condition_code; - this.humidity = humidity + "%"; - this.wind = calcDirection(context, wind_dir) + " " + trimSpeed(wind) + speed_unit; - this.speed_unit = speed_unit; - this.last_sync = last_sync; - // Only the current temperature gets the temp_unit added. - this.temp_unit = temp_unit; - this.temp = temp + "°" + temp_unit; - this.low = low + "°"; - this.high = high + "°"; + this.conditionCode = conditionCode; + this.humidity = humidity; + this.wind = wind; + this.windDirection = windDir; + this.speedUnit = speedUnit; + this.timestamp = timestamp; + this.temperature = temp; + this.lowTemperature = low; + this.highTemperature = high; + this.tempUnit = tempUnit; + } + + public int getConditionResource() { + boolean alternativeIcons = Preferences.useAlternateWeatherIcons(mContext); + final String prefix = alternativeIcons ? "weather2_" : "weather_"; + final Resources res = mContext.getResources(); + final int resId = res.getIdentifier(prefix + conditionCode, "drawable", mContext.getPackageName()); + + if (resId != 0) { + return resId; + } + + return alternativeIcons ? R.drawable.weather2_na : R.drawable.weather_na; } - /** - * find the optimal weather string (helper function for translation) - * - * @param conditionCode condition code from Yahoo (this is the main - * identifier which will be used to find a matching translation - * in the project's resources - * @param providedString - * @return either the defaultString (which should be Yahoo's weather - * condition text), or the translated version from resources - */ - public static String getTranslatedConditionString(Context context, int conditionCode, - String providedString) { - int resID = context.getResources().getIdentifier("weather_" + conditionCode, "string", - context.getPackageName()); - return (resID != 0) ? context.getResources().getString(resID) : providedString; + public String getCity() { + return city; } - private String calcDirection(Context context, String degrees) { - try { - int deg = Integer.parseInt(degrees); - if (deg >= 338 || deg <= 22) - return context.getResources().getString(R.string.weather_N); - else if (deg < 68) - return context.getResources().getString(R.string.weather_NE); - else if (deg < 113) - return context.getResources().getString(R.string.weather_E); - else if (deg < 158) - return context.getResources().getString(R.string.weather_SE); - else if (deg < 203) - return context.getResources().getString(R.string.weather_S); - else if (deg < 248) - return context.getResources().getString(R.string.weather_SW); - else if (deg < 293) - return context.getResources().getString(R.string.weather_W); - else if (deg < 338) - return context.getResources().getString(R.string.weather_NW); - else - return ""; - } catch (NumberFormatException e) { + public String getCondition() { + final Resources res = mContext.getResources(); + final int resId = res.getIdentifier("weather_" + conditionCode, "string", mContext.getPackageName()); + + if (resId != 0) { + return res.getString(resId); + } + + return condition; + } + + public Date getTimestamp() { + return new Date(timestamp); + } + + private String getFormattedValue(float value, String unit) { + if (Float.isNaN(highTemperature)) { + return "-"; + } + return sNoDigitsFormat.format(value) + unit; + } + + public String getFormattedTemperature() { + return getFormattedValue(temperature, "°" + tempUnit); + } + + public String getFormattedLow() { + return getFormattedValue(lowTemperature, "°"); + } + + public String getFormattedHigh() { + return getFormattedValue(highTemperature, "°"); + } + + public String getFormattedHumidity() { + return getFormattedValue(humidity, "%"); + } + + public String getFormattedWindSpeed() { + return getFormattedValue(wind, speedUnit); + } + + public String getWindDirection() { + int resId; + + if (windDirection < 0) { return ""; } + + if (windDirection < 23) resId = R.string.weather_N; + else if (windDirection < 68) resId = R.string.weather_NE; + else if (windDirection < 113) resId = R.string.weather_E; + else if (windDirection < 158) resId = R.string.weather_SE; + else if (windDirection < 203) resId = R.string.weather_S; + else if (windDirection < 248) resId = R.string.weather_SW; + else if (windDirection < 293) resId = R.string.weather_W; + else if (windDirection < 338) resId = R.string.weather_NW; + else resId = R.string.weather_N; + + return mContext.getString(resId); } - private String trimSpeed(String speed) { + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("WeatherInfo for "); + builder.append(city); + builder.append("@ "); + builder.append(getTimestamp()); + builder.append(": "); + builder.append(getCondition()); + builder.append("("); + builder.append(conditionCode); + builder.append("), temperature "); + builder.append(getFormattedTemperature()); + builder.append(", low "); + builder.append(getFormattedLow()); + builder.append(", high "); + builder.append(getFormattedHigh()); + builder.append(", humidity "); + builder.append(getFormattedHumidity()); + builder.append(", wind "); + builder.append(getFormattedWindSpeed()); + builder.append(" at "); + builder.append(getWindDirection()); + return builder.toString(); + } + + public String toSerializedString() { + StringBuilder builder = new StringBuilder(); + builder.append(city).append('|'); + builder.append(forecastDate).append('|'); + builder.append(condition).append('|'); + builder.append(conditionCode).append('|'); + builder.append(temperature).append('|'); + builder.append(lowTemperature).append('|'); + builder.append(highTemperature).append('|'); + builder.append(tempUnit).append('|'); + builder.append(humidity).append('|'); + builder.append(wind).append('|'); + builder.append(windDirection).append('|'); + builder.append(speedUnit).append('|'); + builder.append(timestamp); + return builder.toString(); + } + + public static WeatherInfo fromSerializedString(Context context, String input) { + if (input == null) { + return null; + } + + String[] parts = input.split("\\|"); + if (parts == null || parts.length != 13) { + return null; + } + + int conditionCode, windDirection; + long timestamp; + float temperature, low, high, humidity, wind; + try { - return String.valueOf(Math.round(Float.parseFloat(speed))); + conditionCode = Integer.parseInt(parts[3]); + temperature = Float.parseFloat(parts[4]); + low = Float.parseFloat(parts[5]); + high = Float.parseFloat(parts[6]); + humidity = Float.parseFloat(parts[8]); + wind = Float.parseFloat(parts[9]); + windDirection = Integer.parseInt(parts[10]); + timestamp = Long.parseLong(parts[12]); } catch (NumberFormatException e) { - return ""; + return null; } + + return new WeatherInfo(context, + /* city */ parts[0], /* date */ parts[1], /* condition */ parts[2], + conditionCode, temperature, low, high, /* tempUnit */ parts[7], + humidity, wind, windDirection, /* speedUnit */ parts[11], timestamp); } } diff --git a/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java b/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java new file mode 100644 index 0000000..3e24dd7 --- /dev/null +++ b/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2012 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cyanogenmod.lockclock.weather; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.location.Location; +import android.location.LocationManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.AsyncTask; +import android.os.IBinder; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.cyanogenmod.lockclock.ClockWidgetProvider; +import com.cyanogenmod.lockclock.misc.Constants; +import com.cyanogenmod.lockclock.misc.Preferences; + +import java.io.IOException; +import java.util.Date; + +import org.w3c.dom.Document; + +public class WeatherUpdateService extends Service { + private static final String TAG = "WeatherUpdateService"; + private static final boolean D = Constants.DEBUG; + + private static final String URL_YAHOO_API_WEATHER = "http://weather.yahooapis.com/forecastrss?w=%s&u="; + + public static final String ACTION_FORCE_UPDATE = "com.cyanogenmod.lockclock.action.FORCE_WEATHER_UPDATE"; + + private WeatherUpdateTask mTask; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (D) Log.v(TAG, "Got intent " + intent); + + if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED) { + if (D) Log.v(TAG, "Weather update is still active, not starting new update"); + return START_REDELIVER_INTENT; + } + + boolean force = ACTION_FORCE_UPDATE.equals(intent.getAction()); + if (force) { + Preferences.setCachedWeatherInfo(this, 0, null); + } + if (!shouldUpdate(force)) { + Log.d(TAG, "Service started, but shouldn't update ... stopping"); + stopSelf(); + return START_NOT_STICKY; + } + + mTask = new WeatherUpdateTask(); + mTask.execute(); + + return START_REDELIVER_INTENT; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onDestroy() { + if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED) { + mTask.cancel(true); + mTask = null; + } + } + + private boolean shouldUpdate(boolean force) { + ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); + NetworkInfo info = cm.getActiveNetworkInfo(); + + if (info == null || !info.isConnected()) { + if (D) Log.d(TAG, "No network connection is available for weather update"); + return false; + } + + if (!Preferences.showWeather(this)) { + if (D) Log.v(TAG, "Weather isn't shown, skip update"); + return false; + } + + long interval = Preferences.weatherRefreshIntervalInMs(this); + if (interval == 0 && !force) { + if (D) Log.v(TAG, "Interval set to manual and update not forced, skip update"); + return false; + } + + long now = System.currentTimeMillis(); + long lastUpdate = Preferences.lastWeatherUpdateTimestamp(this); + long due = lastUpdate + interval; + + if (D) Log.d(TAG, "Now " + now + " due " + due + "(" + new Date(due) + ")"); + + if (lastUpdate != 0 && now < due) { + if (D) Log.v(TAG, "Weather update is not due yet"); + return false; + } + + return true; + } + + private class WeatherUpdateTask extends AsyncTask<Void, Void, WeatherInfo> { + private WakeLock mWakeLock; + private Context mContext; + + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE = 1; + private static final int RESULT_CANCELLED = 2; + + public WeatherUpdateTask() { + PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + mContext = WeatherUpdateService.this; + } + + @Override + protected void onPreExecute() { + mWakeLock.acquire(); + } + + private String getWoeidForCustomLocation(String location) { + // first try with the cached woeid, no need to constantly query constant information + String woeid = Preferences.getCachedWoeid(mContext); + if (woeid == null) { + woeid = YahooPlaceFinder.geoCode(mContext, location); + } + if (D) Log.v(TAG, "Yahoo location code for " + location + " is " + woeid); + return woeid; + } + + private String getWoeidForCurrentLocation(Location location) { + String woeid = YahooPlaceFinder.reverseGeoCode(mContext, + location.getLatitude(), location.getLongitude()); + if (woeid == null) { + // we couldn't fetch up-to-date information, fall back to cache + woeid = Preferences.getCachedWoeid(mContext); + } + if (D) Log.v(TAG, "Yahoo location code for current geolocation " + location + " is " + woeid); + return woeid; + } + + private Location getCurrentLocation() { + LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + Location location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER); + if (D) Log.v(TAG, "Current location is " + location); + return location; + } + + private Document getDocument(String woeid) { + boolean celcius = Preferences.useMetricUnits(mContext); + String urlWithUnit = URL_YAHOO_API_WEATHER + (celcius ? "c" : "f"); + + try { + return new HttpRetriever().getDocumentFromURL(String.format(urlWithUnit, woeid)); + } catch (IOException e) { + Log.e(TAG, "Couldn't fetch weather data", e); + } + return null; + } + + @Override + protected WeatherInfo doInBackground(Void... params) { + String customLocation = null; + String woeid; + + if (Preferences.useCustomWeatherLocation(mContext)) { + customLocation = Preferences.customWeatherLocation(mContext); + } + + if (customLocation != null) { + woeid = getWoeidForCustomLocation(customLocation); + } else { + Location location = getCurrentLocation(); + woeid = getWoeidForCurrentLocation(location); + } + + if (woeid == null || isCancelled()) { + return null; + } + + Document doc = getDocument(woeid); + if (doc == null || isCancelled()) { + return null; + } + + return new WeatherXmlParser(mContext).parseWeatherResponse(doc); + } + + @Override + protected void onPostExecute(WeatherInfo result) { + finish(result); + } + + @Override + protected void onCancelled() { + finish(null); + } + + private void finish(WeatherInfo result) { + if (result != null) { + long now = System.currentTimeMillis(); + Preferences.setCachedWeatherInfo(mContext, now, result); + scheduleUpdate(mContext, Preferences.weatherRefreshIntervalInMs(mContext)); + + Intent updateIntent = new Intent(mContext, ClockWidgetProvider.class); + sendBroadcast(updateIntent); + } else if (isCancelled()) { + /* cancelled, likely due to lost network - we'll get restarted + * when network comes back */ + } else { + /* failure, schedule next download in 30 minutes */ + long interval = 30 * 60 * 1000; + scheduleUpdate(mContext, interval); + } + + mWakeLock.release(); + stopSelf(); + } + } + + private static void scheduleUpdate(Context context, long timeFromNow) { + AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + long due = System.currentTimeMillis() + timeFromNow; + + if (D) Log.v(TAG, "Scheduling next update at " + new Date(due)); + am.set(AlarmManager.RTC_WAKEUP, due, getUpdateIntent(context, false)); + } + + public static void scheduleNextUpdate(Context context) { + long lastUpdate = Preferences.lastWeatherUpdateTimestamp(context); + if (lastUpdate == 0) { + scheduleUpdate(context, 0); + } else { + long interval = Preferences.weatherRefreshIntervalInMs(context); + scheduleUpdate(context, lastUpdate + interval - System.currentTimeMillis()); + } + } + + public static PendingIntent getUpdateIntent(Context context, boolean force) { + Intent i = new Intent(context, WeatherUpdateService.class); + if (force) { + i.setAction(ACTION_FORCE_UPDATE); + } + return PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT); + } + + public static void cancelUpdates(Context context) { + AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + am.cancel(getUpdateIntent(context, true)); + am.cancel(getUpdateIntent(context, false)); + } +} diff --git a/src/com/cyanogenmod/lockclock/weather/WeatherXmlParser.java b/src/com/cyanogenmod/lockclock/weather/WeatherXmlParser.java index 50c2c98..0a1643f 100644 --- a/src/com/cyanogenmod/lockclock/weather/WeatherXmlParser.java +++ b/src/com/cyanogenmod/lockclock/weather/WeatherXmlParser.java @@ -69,90 +69,67 @@ public class WeatherXmlParser { mContext = context; } + private String getValueForAttribute(Element root, String tagName, String attributeName) { + NamedNodeMap node = root.getElementsByTagName(tagName).item(0).getAttributes(); + if (node == null) { + return null; + } + return node.getNamedItem(attributeName).getNodeValue(); + } + + private float getFloatForAttribute(Element root, String tagName, String attributeName) + throws NumberFormatException { + String value = getValueForAttribute(root, tagName, attributeName); + if (value == null) { + return Float.NaN; + } + return Float.parseFloat(value); + } + + private int getIntForAttribute(Element root, String tagName, String attributeName) + throws NumberFormatException { + String value = getValueForAttribute(root, tagName, attributeName); + if (value == null) { + return -1; + } + return Integer.parseInt(value); + } + public WeatherInfo parseWeatherResponse(Document docWeather) { if (docWeather == null) { Log.e(TAG, "Invalid doc weather"); return null; } - String strCity = null; - String strDate = null; - String strCondition = null; - String strCondition_code = null; - String strTemp = null; - String strTempUnit = null; - String strHumidity = null; - String strWindSpeed = null; - String strWindDir = null; - String strSpeedUnit = null; - String strHigh = null; - String strLow = null; - try { Element root = docWeather.getDocumentElement(); root.normalize(); - NamedNodeMap locationNode = root.getElementsByTagName(PARAM_YAHOO_LOCATION).item(0) - .getAttributes(); - if (locationNode != null) { - strCity = locationNode.getNamedItem(ATT_YAHOO_CITY).getNodeValue(); - } - - NamedNodeMap unitNode = root.getElementsByTagName(PARAM_YAHOO_UNIT).item(0) - .getAttributes(); - - if (locationNode != null) { - strTempUnit = unitNode.getNamedItem(ATT_YAHOO_TEMP_UNIT).getNodeValue(); - strSpeedUnit = unitNode.getNamedItem(ATT_YAHOO_SPEED).getNodeValue(); - } - - NamedNodeMap atmosNode = root.getElementsByTagName(PARAM_YAHOO_ATMOSPHERE).item(0) - .getAttributes(); - if (atmosNode != null) { - strHumidity = atmosNode.getNamedItem(ATT_YAHOO_HUMIDITY).getNodeValue(); - } - - NamedNodeMap conditionNode = root.getElementsByTagName(PARAM_YAHOO_CONDITION).item(0) - .getAttributes(); - if (conditionNode != null) { - strCondition = conditionNode.getNamedItem(ATT_YAHOO_TEXT).getNodeValue(); - strCondition_code = conditionNode.getNamedItem(ATT_YAHOO_CODE).getNodeValue(); - strCondition = WeatherInfo.getTranslatedConditionString(mContext, Integer.parseInt(strCondition_code), strCondition); - strTemp = conditionNode.getNamedItem(ATT_YAHOO_TEMP).getNodeValue(); - strDate = conditionNode.getNamedItem(ATT_YAHOO_DATE).getNodeValue(); - } - - NamedNodeMap temNode = root.getElementsByTagName(PARAM_YAHOO_WIND).item(0) - .getAttributes(); - if (temNode != null) { - strWindSpeed = temNode.getNamedItem(ATT_YAHOO_SPEED).getNodeValue(); - strWindDir = temNode.getNamedItem(ATT_YAHOO_DIRECTION).getNodeValue(); - } - - NamedNodeMap fcNode = root.getElementsByTagName(PARAM_YAHOO_FORECAST).item(0).getAttributes(); - if (fcNode != null) { - strHigh = fcNode.getNamedItem(ATT_YAHOO_TODAY_HIGH).getNodeValue(); - strLow = fcNode.getNamedItem(ATT_YAHOO_TODAY_LOW).getNodeValue(); - } + WeatherInfo w = new WeatherInfo(mContext, + /* city */ getValueForAttribute(root, PARAM_YAHOO_LOCATION, ATT_YAHOO_CITY), + /* forecastDate */ getValueForAttribute(root, PARAM_YAHOO_CONDITION, ATT_YAHOO_DATE), + /* condition */ getValueForAttribute(root, PARAM_YAHOO_CONDITION, ATT_YAHOO_TEXT), + /* conditionCode */ getIntForAttribute(root, PARAM_YAHOO_CONDITION, ATT_YAHOO_CODE), + /* temperature */ getFloatForAttribute(root, PARAM_YAHOO_CONDITION, ATT_YAHOO_TEMP), + /* low */ getFloatForAttribute(root, PARAM_YAHOO_FORECAST, ATT_YAHOO_TODAY_LOW), + /* high */ getFloatForAttribute(root, PARAM_YAHOO_FORECAST, ATT_YAHOO_TODAY_HIGH), + /* tempUnit */ getValueForAttribute(root, PARAM_YAHOO_UNIT, ATT_YAHOO_TEMP_UNIT), + /* humidity */ getFloatForAttribute(root, PARAM_YAHOO_ATMOSPHERE, ATT_YAHOO_HUMIDITY), + /* wind */ getFloatForAttribute(root, PARAM_YAHOO_WIND, ATT_YAHOO_SPEED), + /* windDir */ getIntForAttribute(root, PARAM_YAHOO_WIND, ATT_YAHOO_DIRECTION), + /* speedUnit */ getValueForAttribute(root, PARAM_YAHOO_UNIT, ATT_YAHOO_SPEED), + System.currentTimeMillis()); + + Log.d(TAG, "Weather updated: " + w); + return w; } catch (Exception e) { - Log.e(TAG, "Something wrong with parser data: " + e.toString()); + Log.e(TAG, "Couldn't parse Yahoo weather XML", e); return null; } - - /* Weather info */ - WeatherInfo yahooWeatherInfo = new WeatherInfo(mContext, strCity, strDate, strCondition, strCondition_code, strTemp, - strTempUnit, strHumidity, strWindSpeed, strWindDir, strSpeedUnit, strLow, strHigh, System.currentTimeMillis()); - - Log.d(TAG, "Weather updated for " + strCity + ": " + strDate + ", " + strCondition + "(" + strCondition_code - + "), " + strTemp + strTempUnit + ", " + strHumidity + "% humidity, " + ", wind: " + strWindDir + " at " - + strWindSpeed + strSpeedUnit + ", low: " + strLow + strTempUnit + " high: " + strHigh + strTempUnit); - - return yahooWeatherInfo; } public String parsePlaceFinderResponse(String response) { try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new InputSource(new StringReader(response))); @@ -170,7 +147,7 @@ public class WeatherXmlParser { } } } catch (Exception e) { - Log.e(TAG, e.toString()); + Log.e(TAG, "Couldn't parse Yahoo place finder XML", e); } return null; } diff --git a/src/com/cyanogenmod/lockclock/weather/YahooPlaceFinder.java b/src/com/cyanogenmod/lockclock/weather/YahooPlaceFinder.java index 569cef1..c2b3f0d 100644 --- a/src/com/cyanogenmod/lockclock/weather/YahooPlaceFinder.java +++ b/src/com/cyanogenmod/lockclock/weather/YahooPlaceFinder.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 The CyanogenMod Project (DvTonder) * Copyright (C) 2012 The AOKP Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,25 +18,43 @@ package com.cyanogenmod.lockclock.weather; import android.content.Context; +import android.content.SharedPreferences; + +import com.cyanogenmod.lockclock.misc.Preferences; public class YahooPlaceFinder { - private static final String YAHOO_API_BASE_REV_URL = "http://where.yahooapis.com/geocode?appid=jYkTZp64&q=%1$s,+%2$s&gflags=R"; - private static final String YAHOO_API_BASE_URL = "http://where.yahooapis.com/geocode?appid=jYkTZp64&q=%1$s"; + private static final String YAHOO_API_BASE_REV_URL = "http://where.yahooapis.com/geocode?appid=EKvCnl4k&q=%1$s,+%2$s&gflags=R"; + private static final String YAHOO_API_BASE_URL = "http://where.yahooapis.com/geocode?appid=EKvCnl4k&q=%1$s"; public static String reverseGeoCode(Context c, double latitude, double longitude) { - String url = String.format(YAHOO_API_BASE_REV_URL, String.valueOf(latitude), String.valueOf(longitude)); String response = new HttpRetriever().retrieve(url); - return new WeatherXmlParser(c).parsePlaceFinderResponse(response); - + if (response == null) { + return null; + } + + String woeid = new WeatherXmlParser(c).parsePlaceFinderResponse(response); + if (woeid != null) { + // cache the result for potential reuse - the placefinder service API is rate limited + Preferences.setCachedWoeid(c, woeid); + } + return woeid; } - public static String GeoCode(Context c, String location) { + public static String geoCode(Context c, String location) { String url = String.format(YAHOO_API_BASE_URL, location).replace(' ', '+'); String response = new HttpRetriever().retrieve(url); - return new WeatherXmlParser(c).parsePlaceFinderResponse(response); + if (response == null) { + return null; + } + + String woeid = new WeatherXmlParser(c).parsePlaceFinderResponse(response); + if (woeid != null) { + // cache the result for potential reuse - the placefinder service API is rate limited + Preferences.setCachedWoeid(c, woeid); + } + return woeid; } - } |