Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d86503d7 authored by Ricardo Cerqueira's avatar Ricardo Cerqueira Committed by Gerrit Code Review
Browse files

Merge "Framework: Lock screen weather (Part 2 of 2)" into ics

parents 8de78331 b0a4ed83
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -2394,6 +2394,48 @@ public final class Settings {
         */
        public static final String QUIET_HOURS_DIM = "quiet_hours_dim";

        /**
         * Show the weather on the lock screen
         * @hide
         */
        public static final String LOCKSCREEN_WEATHER = "lockscreen_weather";

        /**
         * Show the current weather location on the lock screen
         * @hide
         */
        public static final String WEATHER_SHOW_LOCATION = "weather_show_location";

        /**
         * Show the current weather location on the lock screen
         * @hide
         */
        public static final String WEATHER_SHOW_TIMESTAMP = "weather_show_timestamp";

        /**
         * Use the custom/manually configured weather location
         * @hide
         */
        public static final String WEATHER_USE_CUSTOM_LOCATION = "weather_use_custom_location";

        /**
         * Stores the custom/manually configured weather location
         * @hide
         */
        public static final String WEATHER_CUSTOM_LOCATION = "weather_custom_location";

        /**
         * Stores the weather update frequency
         * @hide
         */
        public static final String WEATHER_UPDATE_INTERVAL = "weather_update_interval";

        /**
         * Use Metric measurements (celcius, km/h) for weather data
         * @hide
         */
        public static final String WEATHER_USE_METRIC = "weather_use_metric";

        /**
         * Settings to backup. This is here so that it's in the same place as the settings
         * keys and easy to update.
+141 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The AOKP 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.android.internal.util.weather;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import android.util.Log;

public class HttpRetriever {

    private final String TAG = getClass().getSimpleName();
    private DefaultHttpClient client = new DefaultHttpClient();
    private HttpURLConnection httpConnection;

    public String retrieve(String url) {
        HttpGet get = new HttpGet(url);
        try {
            HttpResponse getResponse = client.execute(get);
            HttpEntity getResponseEntity = getResponse.getEntity();
            if (getResponseEntity != null) {
                String response = EntityUtils.toString(getResponseEntity);
                return response;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void requestConnectServer(String strURL) throws IOException {
        httpConnection = (HttpURLConnection) new URL(strURL).openConnection();
        httpConnection.connect();

        if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            Log.e(TAG, "Something wrong with connection");
            httpConnection.disconnect();
            throw new IOException("Error in connection: " + httpConnection.getResponseCode());
        }
    }

    private void requestDisconnect() {
        if (httpConnection != null) {
            httpConnection.disconnect();
        }
    }

    public Document getDocumentFromURL(String strURL) throws IOException {
        if (strURL == null) {
            Log.e(TAG, "Invalid input URL");
            return null;
        }

        // Connect to server, get data and close
        requestConnectServer(strURL);
        String strDocContent = getDataFromConnection();
        requestDisconnect();

        if (strDocContent == null) {
            Log.e(TAG, "Cannot get XML content");
            return null;
        }

        int strContentSize = strDocContent.length();
        StringBuffer strBuff = new StringBuffer();
        strBuff.setLength(strContentSize + 1);
        strBuff.append(strDocContent);
        ByteArrayInputStream is = new ByteArrayInputStream(strDocContent.getBytes());

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db;
        Document docData = null;

        try {
            db = dbf.newDocumentBuilder();
            docData = db.parse(is);
        } catch (Exception e) {
            Log.e(TAG, "Parser data error");
            return null;
        }
        return docData;
    }

    private String getDataFromConnection() throws IOException {
        if (httpConnection == null) {
            Log.e(TAG, "Connection is null");
            return null;
        }

        String strValue = null;
        InputStream inputStream = httpConnection.getInputStream();
        if (inputStream == null) {
            Log.e(TAG, "Input stream error");
            return null;
        }

        StringBuffer strBuf = new StringBuffer();
        BufferedReader buffReader = new BufferedReader(new InputStreamReader(inputStream));
        String strLine = "";

        while ((strLine = buffReader.readLine()) != null) {
            strBuf.append(strLine + "\n");
            strValue += strLine + "\n";
        }

        // Release resource to system
        buffReader.close();
        inputStream.close();
        return strBuf.toString();
    }
}
+107 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The AOKP 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.android.internal.util.weather;

import android.content.Context;
import com.android.internal.R;

public class WeatherInfo {

    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;
    }

    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) {
        this.city = city;
        this.forecast_date = 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.toLowerCase();
        this.low = low + "°";
        this.high = high + "°";
    }

    /**
     * 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;
    }

    private String calcDirection(Context context, String degrees) {
        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 "";
    }

    private String trimSpeed(String speed) {
        return String.valueOf(Math.round(Float.parseFloat(speed)));
    }
}
+169 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The AOKP 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.android.internal.util.weather;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import android.content.Context;
import android.util.Log;

public class WeatherXmlParser {

    protected static final String TAG = "WeatherXmlParser";

    /** Yahoo attributes */
    private static final String PARAM_YAHOO_LOCATION = "yweather:location";
    private static final String PARAM_YAHOO_UNIT = "yweather:units";
    private static final String PARAM_YAHOO_ATMOSPHERE = "yweather:atmosphere";
    private static final String PARAM_YAHOO_CONDITION = "yweather:condition";
    private static final String PARAM_YAHOO_WIND = "yweather:wind";
    private static final String PARAM_YAHOO_FORECAST = "yweather:forecast";

    private static final String ATT_YAHOO_CITY = "city";
    private static final String ATT_YAHOO_TEMP = "temp";
    private static final String ATT_YAHOO_CODE = "code";
    private static final String ATT_YAHOO_TEMP_UNIT = "temperature";
    private static final String ATT_YAHOO_HUMIDITY = "humidity";
    private static final String ATT_YAHOO_TEXT = "text";
    private static final String ATT_YAHOO_DATE = "date";
    private static final String ATT_YAHOO_SPEED = "speed";
    private static final String ATT_YAHOO_DIRECTION = "direction";
    private static final String ATT_YAHOO_TODAY_HIGH = "high";
    private static final String ATT_YAHOO_TODAY_LOW = "low";

    private Context mContext;

    public WeatherXmlParser(Context context) {
        mContext = context;
    }

    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();
            }
        } catch (Exception e) {
            Log.e(TAG, "Something wrong with parser data: " + e.toString());
            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)));

            NodeList resultNodes = doc.getElementsByTagName("Result");

            Node resultNode = resultNodes.item(0);
            NodeList attrsList = resultNode.getChildNodes();

            for (int i = 0; i < attrsList.getLength(); i++) {
                Node node = attrsList.item(i);
                Node firstChild = node.getFirstChild();
                if ("woeid".equalsIgnoreCase(node.getNodeName()) && firstChild != null) {
                    return firstChild.getNodeValue();
                }
            }
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return null;
    }
}
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The AOKP 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.android.internal.util.weather;

import android.content.Context;

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";

    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);

    }

    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);
    }

}
Loading