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,结束了,欢迎各位童鞋一起来讨论哈,有好的想法也希望能够告诉我。可怜

 





 

0 0
原创粉丝点击