Android 根据城市获取天气(天气预报)
来源:互联网 发布:优化布林线源码 编辑:程序博客网 时间:2024/05/21 09:20
因为项目中需要用到天气预报功能,所以就自己研究了下,
欢迎转载请加地址http://blog.csdn.net/jing110fei/article/details/38515275
首先得找到一个能用的接口,网上出现频率最高的接口是
http://m.weather.com.cn/data/101070101.html 其中101070101就是城市对应的ID
但是完成后,发现此接口2014年3月4日以后就不再更新了
然后又开始寻找,最后还是中国天气网的另一个接口http://m.weather.com.cn/atad/101070101.html 这个是可以用的。
找到可以用的接口,基本就松口气了,接下来就是取数据的事了。
怎么取数据呢,我们一般是输入一个城市名字,期望得到它未来三天的天气状况,
看上面的接口就知道我们需要解决另一个问题,就是城市对应的ID,我也很抓狂,幸好在网上有前辈整理了基本全部的城市ID。。PS:不得不在这里给这位前辈点个赞!
如上图,将此文件放在了assets文件夹下,好了废话不说,贴出主要代码。
主文件的布局文件activity_weather_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"><LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/city_name" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="请输入城市名字" android:layout_weight="1"/> <Button android:id="@+id/query_cityID" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="查询城市ID" /></LinearLayout><LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/city_id" android:layout_width="0dp" android:layout_height="wrap_content" android:background="@drawable/setbar_bg" android:hint="将在此处显示城市ID" android:textSize="18sp" android:layout_weight="1"/> <Button android:id="@+id/query_weather" android:layout_width="0dp" android:layout_height="wrap_content" android:text="查询天气" android:layout_weight="1" /></LinearLayout> <ListView android:id="@+id/query_list" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
然后是listview的显示布局listview_form.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/name" android:layout_width="100dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" /> <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" /></LinearLayout>
然后是主MainActivity的代码WeatherMainActivity.java
public class WeatherMainActivity extends Activity implements OnClickListener {//定义 输入城市名字控件private EditText citynameText;//定义查询城市ID和查询天气的两个Buttonprivate Button query_city_id,query_weather;//定义显示城市ID的TextViewprivate TextView cityIDView;//listview用于显示查询到的天气信息private ListView listview;//listview需要的显示格式即是一个个的键值对,比如天气--------晴private HashMap<String,String> message_map;//listview需要的天气显示格式 将上面的键值对全部存起来private ArrayList<HashMap<String,String>> message_list;//用于线程间通讯private Handler handler;//发送消息更新视图private static final int VIEW_UPDATE=1;private SimpleAdapter SA;//查询天气线程private Thread thread;//定义城市名字和IDString name="";String id="";//判断获取天气数据成功与否的标识private int count=0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_weather_main); citynameText=(EditText)findViewById(R.id.city_name); cityIDView=(TextView)findViewById(R.id.city_id); //用来查找城市ID query_city_id=(Button)findViewById(R.id.query_cityID); query_city_id.setOnClickListener(this); //用来查询天气 query_weather=(Button)findViewById(R.id.query_weather); query_weather.setOnClickListener(this); message_list = new ArrayList<HashMap<String,String>>();listview = (ListView)findViewById(R.id.query_list);SA = new SimpleAdapter(this, message_list, R.layout.listview_form, new String[]{"name","message"}, new int[]{R.id.name,R.id.message});listview.setAdapter(SA);//定义handle对返回结果进行响应handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case VIEW_UPDATE://更新listView的数据SA.notifyDataSetChanged();break;case 3:Toast.makeText(WeatherMainActivity.this, "查询天气失败,可能是网络原因,请检查网络连接", Toast.LENGTH_SHORT).show();break;default:break;}}}; }public void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.query_cityID:name=citynameText.getText().toString();id=findId(name);if(null==id||"".equals(id)){Toast.makeText(WeatherMainActivity.this, "在集合中,没有找到对应城市id", 1).show();}else{cityIDView.setText(id);}break;case R.id.query_weather:if (null==id||"".equals(id)) {Toast.makeText(WeatherMainActivity.this, "请先查询城市ID", 1).show();}else {queryWeather();}break;default:break;}}private String findId(String cityname){ if(null==cityname||"".equals(cityname)) return null; try { InputStreamReader inputReader = new InputStreamReader(getResources().getAssets().open("citycode.txt") ); BufferedReader bufReader = new BufferedReader(inputReader); String line=""; String[] str = new String[2]; while((line = bufReader.readLine()) != null){ str = line.split("="); if(str.length==2&&null!=str[1]&&!"".equals(str[1])&&cityname.equals(str[1])){ //返回对应编号 return str[0]; } } } catch (Exception e) { e.printStackTrace(); return null; } return null;} // 向中国天气网查询数据 private void queryWeather(){thread = new Thread(){@Overridepublic void run() {super.run();//创建返回的天气信息对象,是一个对象数组,用来放3天的天气WeatherForm[] WF = new WeatherForm[3];//查询天气,返回3天的天气信息WeatherQueryManage WQM = new WeatherQueryManageImpl();WF = WQM.weatherquery(id);message_list.clear();if(WF.length>=1){message_map = new HashMap<String, String>();message_map.put("name", WF[0].getName()+":");message_map.put("message", WF[0].getDdate()+"-"+WF[0].getWeek());message_list.add(message_map);for(int i=0;i<WF.length;i++){message_map = new HashMap<String, String>();if(i==0){message_map.put("name", "--------");message_map.put("message", "--------今天--------------");message_list.add(message_map);} if(i==1){message_map.put("name", "--------");message_map.put("message", "--------明天--------------");message_list.add(message_map);} if(i==2){message_map.put("name", "--------");message_map.put("message", "--------后天--------------");message_list.add(message_map);} message_map = new HashMap<String, String>();message_map.put("name", "温度:");message_map.put("message",WF[i].getTemp());message_list.add(message_map);message_map = new HashMap<String, String>();message_map.put("name", "天气状况:");message_map.put("message", WF[i].getWeather());message_list.add(message_map);message_map = new HashMap<String, String>();message_map.put("name", "风力:");message_map.put("message", WF[i].getWind());message_list.add(message_map);if(WF[i].getWind()==null||"".equals(WF[i].getWind())){++count;}}}if(count==3){Message message = new Message();message.what=count;handler.sendMessage(message);}else {Message message = new Message();message.what=VIEW_UPDATE;handler.sendMessage(message);}}};thread.start();}}
接下来是查询到的数据定义为天气对象WeatherForm.java
public class WeatherForm {//城市名private String name;//城市编号private String id;//当前日期private String ddate;//星期private String week;//温度private String temp;//天气描述private String weather;//风力private String wind;//风向private String fx;public WeatherForm(){}public WeatherForm(String name, String id, String ddate, String week,String temp, String weather, String wind, String fx) {super();this.name = name;this.id = id;this.ddate = ddate;this.week = week;this.temp = temp;this.weather = weather;this.wind = wind;this.fx = fx;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getDdate() {return ddate;}public void setDdate(String ddate) {this.ddate = ddate;}public String getWeek() {return week;}public void setWeek(String week) {this.week = week;}public String getTemp() {return temp;}public void setTemp(String temp) {this.temp = temp;}public String getWeather() {return weather;}public void setWeather(String weather) {this.weather = weather;}public String getWind() {return wind;}public void setWind(String wind) {this.wind = wind;}public String getFx() {return fx;}public void setFx(String fx) {this.fx = fx;}@Overridepublic String toString() {return "WeatherForm [name=" + name + ", id=" + id + ", ddate=" + ddate+ ", week=" + week + ", temp=" + temp + ", weather=" + weather+ ", wind=" + wind + ", fx=" + fx + "]";}}
接下来是查询天气的接口的定义WeatherQueryManage.java
public interface WeatherQueryManage { //查询天气方法 // 参数 CityId 对应城市的id //返回值 暂时返回3天的天气数据public WeatherForm[] weatherquery(String CityId);}
然后是对应接口的实现
public class WeatherQueryManageImpl implements WeatherQueryManage {public WeatherForm[] weatherquery(String CityId) {WeatherForm[] WF = new WeatherForm[3];//http://m.weather.com.cn/data/101070101.html//String URL = "http://m.weather.com.cn/data/"+CityId+".html";//http://m.weather.com.cn/atad/101070101.htmlString URL="http://m.weather.com.cn/atad/"+CityId+".html";String Weather_Result="";HttpGet httpRequest = new HttpGet(URL);// 获得HttpResponse对象try {HttpClient httpClient = new DefaultHttpClient();HttpResponse httpResponse = httpClient.execute(httpRequest);if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {// 取得返回的数据Weather_Result = EntityUtils.toString(httpResponse.getEntity());}} catch (Exception e) {WF[0] = new WeatherForm();WF[1] = new WeatherForm();WF[2] = new WeatherForm();return WF;}//以下是对返回JSON数据的解析if(null!=Weather_Result&&!"".equals(Weather_Result)){try {JSONObject JO = new JSONObject(Weather_Result).getJSONObject("weatherinfo");//for(int i=0;i<WF.length;i++){WeatherForm weaf = new WeatherForm();weaf.setName(JO.getString("city"));weaf.setDdate(JO.getString("date_y"));weaf.setWeek(JO.getString("week"));weaf.setTemp(JO.getString("temp"+(i+1)));weaf.setWind(JO.getString("wind"+(i+1)));weaf.setWeather(JO.getString("weather"+(i+1)));WF[i]=weaf;}} catch (JSONException e) {WF[0] = new WeatherForm();WF[1] = new WeatherForm();WF[2] = new WeatherForm();return WF;}}return WF;}}
以上就是全部代码了。。。我这里运行正常,在接口的实现里,第一个注释掉的网址就是之前说的那个不更新的那个地址
对了,别忘了在AndroidManifest.xml中加上访问网络的权限。
<uses-permission android:name="android.permission.INTERNET"/>
OK,结束了,欢迎各位童鞋一起来讨论哈,有好的想法也希望能够告诉我。
- Android 根据城市获取天气(天气预报)
- 根据城市获取天气预报
- 根据城市名获取天气
- 使用天气预报api(中国天气网)获取城市天气(1)---async/await 异步编程
- 使用天气预报api(中国天气网)获取城市天气(2)---httpclient和json操作
- Android开发 获取天气预报(天气,气温,风力...)WebService
- 根据城市查询天气
- android webservice获取城市天气情况
- android webservice获取城市天气情况
- android webservice获取城市天气情况
- android webservice获取城市天气情况
- Android 获取指定城市的天气实况
- 根据坐标点/城市名称获取天气信息
- PHP 根据城市获取天气信息 阿里云接口
- [Android] AlertDialog获取网上天气并显示各城市天气
- 中国天气网 天气预报API 国家气象局 根据城市名称抓取城市ID,XML格式、JSON格式、图片代码
- 中国天气网 天气预报API 国家气象局 根据城市名称抓取城市ID,XML格式、JSON格式、图片代码
- 中国天气网 天气预报API 国家气象局 根据城市名称抓取城市ID,XML格式、JSON格式、图片代码
- 关于机器学习 SVM 支持向量机 文章的小结
- 两台服务器网站同步镜像
- MySQL 最常用的一千行
- Why is it so hard to make a Java program appear native?
- C#知识点之二
- Android 根据城市获取天气(天气预报)
- 远程视频监控之驱动篇(摄像头)
- Linux date命令
- 关于UIView的autoresizingMask属性的研究
- 阿里云centos 静默安装oracle
- 页面动态设置锚点方法
- "LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏"的问题的解决
- mysql中的跨库关联查询
- 查询整个数据库中某个特定值所在的表和字段(存储过程)