android天气实现

来源:互联网 发布:什么叫软件 编辑:程序博客网 时间:2024/05/16 00:28

因公司需要实现一个天气控件,研究了一下天气实现。使用的是雅虎天气。简单实现效果图:


实现思路:

1.开启一个任务Task去访问雅虎天气接口.

2.编写一个control类去解析获取的数据

3.更新UI界面


雅虎获取天气接口:

/**根据城市的名称获取city id,城市的名称可以是中文也是可以英文*/
    private static final String URL_WEATHER_CITYID = "http://sugg.us.search.yahoo.net/gossip-gl-location/?appid=weather&output=xml&command=";(xml:代表输出格式,填json也可以 根据爱好来;command表示的是要输入的城市 如:深圳)

/**根据城市的id和度量单位获取天气**/
    private static final String URL_WEATHER = "http://weather.yahooapis.com/forecastrss?w=%s&u=%s";(w表示的是城市的id , u表示的是温度单位)

1、根据城市名称获取城市id

 public  String getCityId(String city){        Device device = ConfigManager.instance().getDevice() ;        String currentCity ;        String cityId = null;        double distance =-1;        LatLng pt1= new LatLng( device.getLatitude(), device.getLongitude());        try {            currentCity = city==null?device.getCity():city ;            String url = URL_WEATHER_CITYID + URLEncoder.encode(currentCity, ENCODING);            String result_str = getDataToUrl(url);            //result_str 里面包含许多城市信息  通过当前位置的经纬度选取最合适的城市id            String[] strs = result_str.split("<s") ;            for(String str :strs){                String[] datas = str.split("&") ;                if(datas.length>2){                    double tmpLon = -1;                    double tmpLat = -1;                    String tmpCityid =null;                    for(String data :datas){                        if(data.startsWith("lon=")){                            tmpLon =Double.parseDouble(data.substring(data.indexOf("lon=") + 4)) ;                        }                        if(data.startsWith("lat=")){                            tmpLat = Double.parseDouble(data.substring(data.indexOf("lat=") + 4)) ;                        }                        if(data.startsWith("woeid=")){                            tmpCityid = data.substring(data.indexOf("woeid=")+6) ;                        }                        if(tmpLon!=-1 && tmpLat!=-1 && tmpCityid!=null){ //均赋值  比较经纬度                            LatLng pt2 = new LatLng(tmpLat, tmpLon);                            double dis = DistanceUtil.getDistance(pt1 , pt2) ;                            if(distance==-1 || dis<distance){                                cityId = tmpCityid ;                                distance = dis ;                                Log.v("snamon" , "交换距离...") ;                            }                            break;                        }                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        return cityId ;    }
上面代码可能有点复杂,因为我这里有个业务逻辑。因为根据我们传过来的城市可能会得到多个城市id如:

http://sugg.us.search.yahoo.net/gossip-gl-location/?appid=weather&output=xml&command=%E6%B7%B1%E5%9C%B3

得到结果:

<m q="深圳" gprid="xvhOMS5dTZ2dRzr_FcExWA" n="3"><s k="Shenzhen (深圳市)" d="pt:iso=CN&woeid=2161853&lon=114.113&lat=22.5468&s=Guangdong&c=China&country_woeid=23424781&pn=深圳市&n=Shenzhen (深圳市), Guangdong, China"/><s k="Shenzhen" d="ct:iso=CN&woeid=26198346&lon=114.19&lat=22.6441&s=Guangdong&c=China&country_woeid=23424781&pn=深圳市&n=Shenzhen, Guangdong, China"/><s k="深圳村" d="su:iso=TW&woeid=28758009&lon=121.011&lat=24.9613&t=桃園市&s=桃園市&c=台灣&country_woeid=23424971&n=深圳村, 桃園市, 桃園市, 台灣"/></m>
我选距离我当前位置最近的一个城市 。如果直接定位当前的天气,则直接取第一条数据就好了。


2、根据上述获取到城市id获取天气

 /**     * 根据城市id获取天气     * @param cityId     * @return     */    public  WeatherInfo getWeatherInfo(String cityId){        if(cityId == null ){            return null ;        }
<span style="white-space:pre"></span>//METRIC表示的是温度单位 这是直接填"<span style="font-family: Arial, Helvetica, sans-serif;">c"</span>
        String url = String.format(URL_WEATHER, cityId, METRIC);        Log.d("snamon", "getWeatherInfo :  " + url);
<span style="white-space:pre"></span>//这里直接获取网页数据        String response = retrieve(url); /        if (response == null) {            return null;        }        // 开始对雅虎天气的XML文件解析操作        SAXParserFactory factory = SAXParserFactory.newInstance();        try {            SAXParser parser = factory.newSAXParser() ;            StringReader reader = new StringReader(response) ;            WeatherHandler weatherHandler = new WeatherHandler();            parser.parse(new InputSource(reader), weatherHandler);            WeatherInfo weatherInfo = weatherHandler.getWeatherInfo() ;            return weatherInfo ;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }

上面的操作很简单,主要是对返回过来的天气xml解析

3、解析天气数据

/**     * sax天气解析Handler     */    private  class WeatherHandler extends DefaultHandler {        WeatherInfo mWeatherInfo = new WeatherInfo();        WeatherInfo.DayInfo mDayInfo  ;        List<WeatherInfo.Forecast> mForecasts ;        String speedUnit ;  //这是风力速度单位        String temperatureUnit ; //这是温度单位        public WeatherHandler(){            mDayInfo =  new WeatherInfo.DayInfo() ;            mForecasts = new ArrayList<WeatherInfo.Forecast>() ;        }        public WeatherInfo getWeatherInfo(){            return mWeatherInfo;        }        @Override        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {            if (qName.equals("yweather:units")) {                temperatureUnit = "°"+attributes.getValue("temperature");                speedUnit = attributes.getValue("speed");            } else if (qName.equals("yweather:wind")) {                mDayInfo.windDirection = attributes.getValue("direction");                mDayInfo.windSpeed = attributes.getValue("speed")+speedUnit;            } else if (qName.equals("yweather:atmosphere")) {                mDayInfo.humidity = attributes.getValue("humidity");//温度            } else if (qName.equals("yweather:astronomy")) {  //日出、日落                mDayInfo.sunrise = attributes.getValue("sunrise");                mDayInfo.sunset = attributes.getValue("sunset");            } else if (qName.equals("yweather:condition")) {                mDayInfo.condition = attributes.getValue("text");                mDayInfo.conditionCode = attributes.getValue("code");                mDayInfo.temperature = attributes.getValue("temp")+temperatureUnit;                String[] dateList = attributes.getValue("date").split(",")[1].trim().split(" ");                mDayInfo.date = String.format("%s %s %s", dateList[0], dateList[1], dateList[2]);            } else if (qName.equals("yweather:forecast")) {                WeatherInfo.Forecast forecast = new WeatherInfo.Forecast() ;                forecast.day = attributes.getValue("day") ;                forecast.condition= attributes.getValue("text") ;                forecast.conditionCode = attributes.getValue("code") ;                String data[] = attributes.getValue("date").trim().split(" ");                StringBuilder builder = new StringBuilder();                if (Integer.parseInt(data[0]) < 10)                    builder.append("0");                builder.append(data[0]);                builder.append(" ");                builder.append(changeDate(data[1].trim()));                builder.append(" ");                builder.append(data[2]);                forecast.date = builder.toString() ;                forecast.high = attributes.getValue("high")+temperatureUnit;                forecast.low = attributes.getValue("low") + temperatureUnit;                mForecasts.add(forecast) ;            }        }        @Override        public void endDocument() throws SAXException {            mWeatherInfo.mDayInfo = mDayInfo ;            mWeatherInfo.mForecasts = mForecasts ;        }        /**         * 转换日期         * @param str         * @return         */        private String changeDate(String str){            if("Jan".equals(str)){                return "1" ;            }else if("Feb".equals(str)){                return "2" ;            }else if("Mar".equals(str)){                return "3" ;            }else if("Apr".equals(str)){                return "4" ;            }else if("May".equals(str)){                return "5";            }else if("Jun".equals(str)){                return "6" ;            }else if("Jul".equals(str)){                return "7" ;            }else  if("Aug".equals(str)){                return "8";            }else if("Sept".equals(str)){                return "9" ;            }else if("Oct".equals(str)){                return"10" ;            }else if("Nov".equals(str)){                return "11" ;            }else  if("Dec".equals(str)){                return "12" ;            }else                return str ;        }    }

我是通过SAX  handler来解析 。方法很多种 可以自己进行熟悉的解析方法 。


这个天气控件就三个控件 。WeatherControl (负责获取和解析数据) , WeatherInfo(天气实体对象) , weatherView(显示控件)

上面是核心代码 。整个控件没独立出来 。

下载完整代码:

http://download.csdn.net/detail/otc_yan/9400512








1 0