Android Open Source - weatherport Weather Loader






From Project

Back to project page weatherport.

License

The source code is released under:

Apache License

If you think the Android project weatherport listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013 Dan Morrill//from   w  w w  . j a  v  a  2  s .c om
 *
 * 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 dude.morrildl.weatherport;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;

import android.util.JsonReader;
import android.util.Log;

import com.google.android.gms.maps.model.LatLng;

/**
 * Utility class that handles network accesses and JSON parsing. This is quick
 * and dirty, but the JSON is extremel simple, so it's okay.
 */
public class WeatherLoader {
    /**
     * Courier POJO to simply carry named values around.
     */
    public static class WeatherInfo {
        public String dewPoint;

        public String elevation;
        public String humidity;
        public String ICAO;
        public int imageId;
        public LatLng latLng;
        public String name;
        public String pressure;
        public String temperature;
        public String windDirection;
        public String windSpeed;

        public WeatherInfo() {
        }
    }

    // Weather data lives here. Can you dig it?
    public static final String GEONAMES_URL = "http://ws.geonames.org/weatherIcaoJSON?ICAO=";

    private static final HashMap<String, Integer> weatherImageMap;
    static {
        // I found a list of string constants in some GNOME sample code somewhere
        weatherImageMap = new HashMap<String, Integer>();

        weatherImageMap.put("drizzle", R.drawable.drizzle);
        weatherImageMap.put("light showers rain", R.drawable.drizzle);
        weatherImageMap.put("light rain", R.drawable.drizzle);

        weatherImageMap.put("rain", R.drawable.rain);

        weatherImageMap.put("light snow", R.drawable.snow);
        weatherImageMap.put("snow grains", R.drawable.snow);

        weatherImageMap.put("few clouds", R.drawable.partly_cloudy);
        weatherImageMap.put("scattered clouds", R.drawable.partly_cloudy);

        weatherImageMap.put("clear sky", R.drawable.sunny);

        weatherImageMap.put("broken clouds", R.drawable.cloudy);
        weatherImageMap.put("overcast", R.drawable.cloudy);

    }

    /**
     * Fetches weather data for given airport code. Will attempt to fetch
     * arbitrary strings; there might be a code injection issue here, but I
     * don't think so, since we never exec the results, only parse it as a JSON
     * string with (one of) the system JSON parser(s).
     * 
     * Probably won't work on airports outside the US, but has no protection
     * against that.
     * 
     * @param airport
     *            a 4-digit airport code, starting with K (which means US)
     * @return a WeatherInfo instance with data, or null if an error occurred
     */
    public static WeatherInfo fetchDataFor(String airport) {
        try {
            URL url = new URL(GEONAMES_URL + airport);
            JsonReader jsonReader = new JsonReader(new BufferedReader(new InputStreamReader(
                    url.openStream())));

            WeatherInfo info = new WeatherInfo();
            String name, value;
            String clouds = null, conditions = null;
            float lat = 0, lng = 0;

            // response is always "{ weatherObservation": { ... } }"
            jsonReader.beginObject();
            jsonReader.nextName();
            jsonReader.beginObject();

            while (jsonReader.hasNext()) {
                name = jsonReader.nextName();
                value = jsonReader.nextString();

                if ("clouds".equals(name)) {
                    clouds = value;
                } else if ("weatherCondition".equals(name)) {
                    conditions = value;
                } else if ("windDirection".equals(name)) {
                    info.windDirection = value;
                } else if ("windSpeed".equals(name)) {
                    info.windSpeed = value;
                } else if ("elevation".equals(name)) {
                    info.elevation = value;
                } else if ("ICAO".equals(name)) {
                    info.ICAO = value;
                } else if ("stationName".equals(name)) {
                    info.name = value;
                } else if ("seaLevelPressure".equals(name)) {
                    info.pressure = value;
                } else if ("temperature".equals(name)) {
                    info.temperature = value;
                } else if ("dewPoint".equals(name)) {
                    info.dewPoint = value;
                } else if ("humidity".equals(name)) {
                    info.humidity = value;
                } else if ("lat".equals(name)) {
                    lat = Float.parseFloat(value);
                } else if ("lng".equals(name)) {
                    lng = Float.parseFloat(value);
                }
            }
            jsonReader.endObject();
            jsonReader.close();

            // combine composite values (i.e. made of multiple keys in the
            // JSON object) after we are done parsing
            if (lat != 0f && lng != 0f) {
                info.latLng = new LatLng(lat, lng);
            }
            info.imageId = getImageIdFor(clouds, conditions);

            return info;
        } catch (IOException e) {
            // The JSON in question is very simple, so we don't worry too much
            // about errors
            Log.e("WeatherLoader", "error fetching or parsing", e);
            return null;
        }
    }

    /**
     * Given two parameters, attempts to recognize map them to an image, for a
     * little eye candy in the UI. Conditions takes precedence over clouds, if
     * present.
     * 
     * @param clouds
     *            from geonames JSON
     * @param conditions
     *            from geonames JSON
     * @return the resource ID of an image appropriate to the given weather
     *         conditions
     */
    private static int getImageIdFor(String clouds, String conditions) {
        Integer id = weatherImageMap.get(conditions);
        if (id == null) {
            id = weatherImageMap.get(clouds);
            if (id == null) {
                Log.w("WeatherLoader", "unrecognized weather code (" + clouds + ", " + conditions
                        + ")");
                return R.drawable.sunny;
            }
        }
        return id;
    }
}




Java Source Code List

dude.morrildl.weatherport.AboutActivity.java
dude.morrildl.weatherport.DetailsFragment.java
dude.morrildl.weatherport.MainActivity.java
dude.morrildl.weatherport.TwoFragmentPagerAdapter.java
dude.morrildl.weatherport.WeatherLoader.java