android天气实现

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


实现思路:

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








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值