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
- android天气实现
- Android实现天气查询
- Android 如何实现google天气
- Android天气类app实现
- Android实现天气预报(中国天气网)
- Android实现天气功能碰到的问题
- 免费天气API Android实现(一)
- Android实现天气预报(中国天气网)
- Android 天气
- Android 实现简单当前时间点的天气情况(和风天气接口)
- Android json解析网络数据实现天气实时查询
- Android使用SurfaceView实现墨迹天气的风车效果
- Android使用SurfaceView实现墨迹天气的风车效果
- Android——调用百度天气API实现天气预报
- Android使用SurfaceView实现墨迹天气的风车效果
- Android实现自动定位城市并获取天气信息
- Android自定义view--SurfaceView实现墨迹天气的风车效果
- Android仿小米天气圆形比率条的实现
- leetcode总结2 -- 找一个特殊的数
- vi在当前行下插入一行并进入插入模式
- Android中Handler引起的内存泄露
- 静态链接库(lib)和动态链接库(dll)的区别和使用
- Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
- android天气实现
- 浅析Android View(二)
- 常用的正则表达式
- [从头学数学] 第39节 万以内的加法和减法(一)
- Android学习(5)---异步消息处理方法小结
- 像老板一样思考问题
- 使用Stanford Word Segmenter and Stanford Named Entity Recognizer (NER)实现英文命名实体识别
- 后台接受中文或者非中文参数终极解决方案
- iOS开发之 Cocoapods MBProgressHUD 安装步骤