Android学习之天气预报简单版

自己想做一个简单的天气预报,由于能力有限,暂时做个简单的。

大概讲一下自己的开发步骤吧。

第一步:获得可以开发的json数据的及时更新的接口。

通过强大的度娘,我这里使用的json的地址是:http://wthrcdn.etouch.cn/weather_mini?citykey=101010100

第二步:实现各大城市编号的获取

实现方法:网上下载一个包含各大城市的db文件db_weather.db,下载地址:http://pan.baidu.com/s/1hqkxlxM

这个db文件里面包含中国各大省份及城市编号,里面的大概内容截图如下所示

这个是省份表:

这个是城市表:

把这个db文件下载下来,通过DDMS,把这个文件放到android测试机的/sdcard目录下

然后编写一些界面响应,获取省份 以及城市的编号,例如北京:101010100

获取省份和城市编号的代码如下

以下是MainActivity的代码(初次写,很多方法没有进行封装,日后有机会进行代码优化)

  1 package com.oysd.mywea;
  2 
  3 import java.io.File;
  4 import java.util.ArrayList;
  5 import java.util.List;
  6 
  7 import android.app.Activity;
  8 import android.content.Intent;
  9 import android.database.Cursor;
 10 import android.database.sqlite.SQLiteDatabase;
 11 import android.os.Bundle;
 12 import android.view.Menu;
 13 import android.view.MenuItem;
 14 import android.view.View;
 15 import android.view.View.OnClickListener;
 16 import android.widget.AdapterView;
 17 import android.widget.AdapterView.OnItemSelectedListener;
 18 import android.widget.ArrayAdapter;
 19 import android.widget.Button;
 20 import android.widget.Spinner;
 21 import android.widget.Toast;
 22 
 23 public class MainActivity extends Activity {
 24     
 25     private File f = new File("/sdcard/weather/db_weather.db");
 26     private Spinner province;//省份
 27     private Spinner city;//城市
 28     private List<String> proset=new ArrayList<String>();//省份集合
 29     private List<String> cityset=new ArrayList<String>();//城市集合
 30     private Button showWea;
 31     private int pro_id;//省份id号
 32     private long city_num;
 33     private String pro_name;
 34     
 35     @Override
 36     protected void onCreate(Bundle savedInstanceState) {
 37         super.onCreate(savedInstanceState);
 38         setContentView(R.layout.activity_main);
 39         
 40         province = (Spinner) findViewById(R.id.provinces);
 41         city = (Spinner) findViewById(R.id.city);
 42         showWea = (Button) findViewById(R.id.showWea);
 43         
 44         ArrayAdapter<String> pro_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getProSet());
 45         province.setAdapter(pro_adapter);
 46         province.setOnItemSelectedListener(new SelectProvince());//添加省份监听
 47         
 48         city.setOnItemSelectedListener(new SelectCity());//添加城市选择监听
 49         showWea.setOnClickListener(new OnClickListener() {
 50             
 51             @Override
 52             public void onClick(View v) {
 53                 // TODO Auto-generated method stub
 54                 
 55                 Bundle b = new Bundle();
 56                 b.putLong("city_num", city_num);
 57                 b.putString("pro_name", pro_name);
 58                 Intent intent = new Intent(MainActivity.this , WeaActivity.class);
 59                 intent.putExtras(b);
 60                 startActivity(intent);
 61             }
 62         });
 63     }
 64     
 65     /**
 66      * 增加省份监听类
 67      * @author Administrator
 68      *
 69      */
 70     class SelectProvince implements OnItemSelectedListener{
 71 
 72         @Override
 73         public void onItemSelected(AdapterView<?> parent, View view, int position,
 74                 long id) {
 75             // TODO Auto-generated method stub
 76             pro_id = position;
 77             pro_name = getProName();
 78             city.setAdapter(getAdapter());
 79         }
 80 
 81         @Override
 82         public void onNothingSelected(AdapterView<?> arg0) {
 83             // TODO Auto-generated method stub
 84             
 85         }
 86         
 87     }
 88     
 89     class SelectCity implements OnItemSelectedListener{
 90 
 91         @Override
 92         public void onItemSelected(AdapterView<?> parent, View view, int position,
 93                 long id) {
 94             // TODO Auto-generated method stub
 95             
 96             String cityname = parent.getItemAtPosition(position).toString();
 97             city_num = getCityNum(position);
 98             
 99             //提示一下
100             Toast.makeText(getApplicationContext(), cityname+":" + city_num, 2000).show();
101             
102         }
103 
104         @Override
105         public void onNothingSelected(AdapterView<?> arg0) {
106             // TODO Auto-generated method stub
107             
108         }
109         
110     }
111     
112     /**
113      * 返回省份集合
114      */
115     public List<String> getProSet(){
116         //打开数据库
117         SQLiteDatabase db1 = SQLiteDatabase.openOrCreateDatabase(f, null);
118         Cursor cursor = db1.query("provinces", null, null, null, null, null, null);
119         while(cursor.moveToNext()){
120             String pro = cursor.getString(cursor.getColumnIndexOrThrow("name"));
121             proset.add(pro);
122         }
123         cursor.close();
124         db1.close();
125         return proset;
126     }
127     
128     /**
129      * 返回城市集合
130      */
131     public List<String> getCitySet(int pro_id){
132         cityset.clear();//清空一下城市列表
133         
134         SQLiteDatabase db2 = SQLiteDatabase.openOrCreateDatabase(f, null);
135         Cursor cursor = db2.query("citys", null, "province_id=" + pro_id, null, null, null, null);
136         while(cursor.moveToNext()){
137             String city = cursor.getString(cursor.getColumnIndexOrThrow("name"));
138             cityset.add(city);
139         }
140         cursor.close();
141         db2.close();
142         return cityset;
143     }
144     
145     /**
146      * 返回城市的编号
147      * @param position
148      * @return
149      */
150     public long getCityNum(int position){
151         SQLiteDatabase db3 = SQLiteDatabase.openOrCreateDatabase(f, null);
152         Cursor cursor = db3.query("citys", null, "province_id=" + pro_id, null, null, null, null);
153         cursor.moveToPosition(position);
154         long citynum = cursor.getLong(cursor.getColumnIndexOrThrow("city_num"));
155         cursor.close();
156         db3.close();
157         return citynum;
158     }
159     
160     /**
161      * 获取省份名字
162      * @return
163      */
164     public String getProName(){
165         SQLiteDatabase db4 = SQLiteDatabase.openOrCreateDatabase(f, null);
166         int pp = pro_id + 1;
167         Cursor cursor = null;
168         
169         cursor = db4.query("provinces", null, "_id=" + pp, null, null, null, null);
170         //cursor.moveToPosition(0);
171         String proname = null;
172         while(cursor.moveToNext()){
173         proname = cursor.getString(cursor.getColumnIndex("name"));
174         }
175         cursor.close();
176         db4.close();
177         return proname;
178     }
179     /**
180      * 返回选择城市的适配器
181      * @return
182      */
183     public ArrayAdapter<String> getAdapter(){
184         ArrayAdapter<String> city_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getCitySet(pro_id));
185         return city_adapter;
186     }
187 }
View Code

以下是这个MainActivity的布局文件(比较简单)

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6 
 7     <TextView
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:text="省份/直辖市"
11         android:textSize="20dp"
12         android:textStyle="bold" />
13 
14     <Spinner
15         android:id="@+id/provinces"
16         android:layout_width="fill_parent"
17         android:layout_height="wrap_content" />
18 
19     <TextView
20         android:layout_width="fill_parent"
21         android:layout_height="wrap_content"
22         android:text="市/县"
23         android:textSize="20dp"
24         android:textStyle="bold" />
25 
26     <Spinner
27         android:id="@+id/city"
28         android:layout_width="fill_parent"
29         android:layout_height="wrap_content" />
30 
31     <Button
32         android:id="@+id/showWea"
33         android:layout_width="fill_parent"
34         android:layout_height="wrap_content"
35         android:text="查看天气" />
36 
37 </LinearLayout>
View Code

通过上面的操作,就能够正确获得省份名字以及选择的城市

第三步:将获得省份名字以及城市编号 与json地址进行拼接,然后获取json数据并且进行解析

这个过程首先与json地址进行拼接然后获得json的字符串数据:

以下是显示某城市的天气情况,里面包含了选择城市的编号与json地址进行拼接

 1 package com.oysd.mywea;
 2 
 3 import java.util.ArrayList;
 4 
 5 import com.google.gson.Gson;
 6 import com.oysd.mywea.WeatherBean.ChildWeatherBean.GrandChildsWeatherBean;
 7 
 8 import android.app.Activity;
 9 import android.os.Bundle;
10 import android.widget.TextView;
11 
12 public class WeaActivity extends Activity {
13     
14     private static String PATH = "http://wthrcdn.etouch.cn/weather_mini?citykey=";
15     private TextView tvCity,tvWendu,tvWenduValue,tvTomWenduValue,tvCurrentWendu,tvNote,tvCurrentCity,tvTomWendu,tvTodayType,tvTomorrowType;
16     
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         // TODO Auto-generated method stub
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_weather);
22         
23         tvCity = (TextView) findViewById(R.id.tvCity);
24         tvWendu = (TextView) findViewById(R.id.tvWendu);
25         tvWenduValue = (TextView) findViewById(R.id.tvWenduValue);
26         tvCurrentWendu = (TextView) findViewById(R.id.tvCurrentWendu);
27         tvNote = (TextView) findViewById(R.id.tvNote);
28         tvCurrentCity = (TextView) findViewById(R.id.tvCurrentCity);
29         tvTomWendu = (TextView) findViewById(R.id.tvTomWendu);
30         tvTodayType = (TextView) findViewById(R.id.tvTodayType);
31         tvTomorrowType = (TextView) findViewById(R.id.tvTomorrowType);
32         tvTomWenduValue = (TextView) findViewById(R.id.tvTomWenduValue);
33         
34         long city_num = getIntent().getExtras().getLong("city_num");
35         String pro_name = getIntent().getExtras().getString("pro_name");
36         tvCity.setText(pro_name + "天气");
37         String path = PATH + city_num;//与json数据的地址进行拼接
38         
39         String JsonString = HttpUtils.getJsonContent(path);//获得json数据的字符串格式
40         
41         WeatherBean bean = getWeatherFromJson(JsonString);//info为正确编码解析后的json数据,在bean中就可以获取第一级的若干参数
42         
43         final WeatherBean.ChildWeatherBean childWeatherBean = bean.data;//这是第二级的javabean,可获取当下的温度以及一些基本参数
44         
45         WeatherBean.ChildWeatherBean.GrandChildWeatherBean grandChildWeahterBean = childWeatherBean.yesterday;
46         
47         //yesterday中的内容算是第三级的内容了,下面这句话也是第三级的内容,只不过这是一个List集合,这里就可以直接获取到了。
48         
49         ArrayList<WeatherBean.ChildWeatherBean.GrandChildsWeatherBean> grandChildsWeatherBeans = childWeatherBean.forecast;
50         GrandChildsWeatherBean TodayWendu = grandChildsWeatherBeans.get(0);
51         String strWendu = "今日温度范围: ";
52         tvWendu.setText(strWendu);
53         tvWenduValue.setText(TodayWendu.low + "
" +TodayWendu.high);
54         
55         String currentWendu = "当前温度: " + childWeatherBean.wendu;
56         tvCurrentWendu.setText(currentWendu);
57         
58         String Note = "注意事项 : " + childWeatherBean.ganmao;
59         tvNote.setText(Note);
60         
61         String currentCity = "所在位置 : " + childWeatherBean.city;
62         tvCurrentCity.setText(currentCity);
63         
64         GrandChildsWeatherBean TomorrowWendu = grandChildsWeatherBeans.get(1);
65         String strTomWendu = "明日温度范围: ";
66         tvTomWendu.setText(strTomWendu);
67         tvTomWenduValue.setText(TomorrowWendu.low + "
" +TomorrowWendu.high);
68         
69         String todayType = "今日天气类型    " + TodayWendu.type;
70         String tomorrowType = "明日天气类型    " + TomorrowWendu.type;
71         
72         tvTodayType.setText(todayType);
73         tvTomorrowType.setText(tomorrowType);
74         
75         
76     }
77     
78     
79     /**
80      * 通过Gson进行json数据的解析
81      * @param json
82      * @return
83      */
84     private WeatherBean getWeatherFromJson(String json) {
85         
86         WeatherBean bean = new Gson().fromJson(json, WeatherBean.class);
87         return bean;
88     }
89 }
View Code

得到json地址之后,通过http协议进行获取json字符串类型的数据:

 1 package com.oysd.mywea;
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.net.HttpURLConnection;
 7 import java.net.MalformedURLException;
 8 import java.net.URL;
 9 
10 public class HttpUtils {
11 
12     public HttpUtils() { 
13     } 
14      
15     /**
16      * 获得json数据(String型)
17      * @param path
18      * @return
19      */
20     public static String getJsonContent(String path){ 
21         try { 
22             URL url = new URL(path); 
23             HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 
24             connection.setConnectTimeout(3000); 
25             connection.setRequestMethod("GET"); 
26             connection.setDoInput(true); 
27             int code = connection.getResponseCode(); 
28             if(code == 200){ 
29                 //获取数据输入流
30                 String str = changeInputStream(connection.getInputStream());
31                 System.out.println(str);
32                 return str;
33             } 
34         } catch (MalformedURLException e) { 
35             e.printStackTrace(); 
36         } catch (IOException e) { 
37             e.printStackTrace(); 
38         } 
39         return null; 
40     } 
41  
42     /** 
43      * 将一个输入流转换成指定编码的字符串
44      * @param inputStream 
45      * @return 
46      */ 
47     private static String changeInputStream(InputStream inputStream) { 
48         String jsonString = ""; 
49         ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
50         int len = 0; 
51         //把输入流转换成字符串
52         byte[] data = new byte[1024]; 
53         try { 
54             while((len=inputStream.read(data))!=-1){ 
55                 outputStream.write(data,0,len); 
56             } 
57             jsonString = new String(outputStream.toByteArray()); 
58         } catch (IOException e) { 
59             e.printStackTrace(); 
60         } 
61         return jsonString; 
62     } 
63 
64 }
View Code

获得String型的json数据之后,就需要对这个json进行解析了,这里使用的是Google的Gson库进行解析,

之所以使用Gson,主要还是因为定义了Bean之后,解析起来非常容易理解,也方便,不过需要针对json的具体格式进行定义相应的java bean

这个json的格式如下(需要直观查看json数据的格式,建议使用http://abv.cn/json/ ,此网址能够将json数据的显示格式显示的层次分明点)

相对应的WeatherBean如下:

 1 package com.oysd.mywea;
 2 
 3 import java.util.ArrayList;
 4 
 5 public class WeatherBean {
 6     public ChildWeatherBean data;
 7     public int status;
 8     public String desc;
 9 
10     public class ChildWeatherBean {
11         public int wendu;
12         public String ganmao;
13         public String city;
14         public GrandChildWeatherBean yesterday;
15         public ArrayList<GrandChildsWeatherBean> forecast;
16 
17         public class GrandChildWeatherBean {
18 
19             public String high;
20             public String fl;
21             public String date;
22             public String low;
23             public String type;
24             public String fx;
25         }
26 
27         public class GrandChildsWeatherBean {
28             public String high;
29             public String fengli;
30             public String fengxiang;
31             public String date;
32             public String low;
33             public String type;
34         }
35     }
36 }
View Code

具体的解析代码截图如下:

这样,数据解析之后,通过实例化对象,将想要的数据获取到,显示到天气情况界面

此界面也相对比较简单:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3     android:layout_width="match_parent"
  4     android:layout_height="match_parent"
  5     android:orientation="vertical" >
  6 
  7     <TextView
  8         android:id="@+id/tvCity"
  9         android:layout_width="fill_parent"
 10         android:layout_height="wrap_content"
 11         android:text="" 
 12         android:textSize="28sp"/>
 13     
 14      <View
 15           android:layout_width="fill_parent"
 16           android:layout_height="2dip"
 17           android:background="#FF0000ff"/>
 18      
 19      <LinearLayout 
 20          android:layout_width="fill_parent"
 21          android:layout_height="wrap_content"
 22          android:orientation="horizontal">
 23          <TextView
 24             android:id="@+id/tvWendu"
 25             android:layout_weight="1"
 26             android:layout_width="wrap_content"
 27             android:layout_height="wrap_content"
 28             android:text="" 
 29             android:textSize="25sp"/>
 30          <TextView
 31             android:id="@+id/tvWenduValue"
 32             android:layout_weight="2"
 33             android:layout_width="wrap_content"
 34             android:layout_height="wrap_content"
 35             android:text="" 
 36             android:textSize="25sp"/>
 37      </LinearLayout>
 38       <View
 39           android:layout_width="fill_parent"
 40           android:layout_height="2dip"
 41           android:background="#FFff0099"/>    
 42  
 43      <TextView
 44         android:id="@+id/tvCurrentWendu"
 45         android:layout_width="fill_parent"
 46         android:layout_height="wrap_content"
 47         android:text="" 
 48         android:textSize="25sp"/>         
 49      <View
 50           android:layout_width="fill_parent"
 51           android:layout_height="2dip"
 52           android:background="#FFff9999"/> 
 53                 
 54      <TextView
 55         android:id="@+id/tvNote"
 56         android:layout_width="fill_parent"
 57         android:layout_height="wrap_content"
 58         android:text="" 
 59         android:textSize="25sp"/>      
 60         
 61       <View
 62           android:layout_width="fill_parent"
 63           android:layout_height="2dip"
 64           android:background="#FF00ff99"/>    
 65           
 66       <TextView
 67         android:id="@+id/tvCurrentCity"
 68         android:layout_width="fill_parent"
 69         android:layout_height="wrap_content"
 70         android:text="" 
 71         android:textSize="25sp"/>         
 72         
 73       <View
 74           android:layout_width="fill_parent"
 75           android:layout_height="2dip"
 76           android:background="#FF001155"/>    
 77           
 78      <LinearLayout 
 79          android:layout_width="fill_parent"
 80          android:layout_height="wrap_content"
 81          android:orientation="horizontal">
 82          <TextView
 83             android:id="@+id/tvTomWendu"
 84             android:layout_weight="1"
 85             android:layout_width="wrap_content"
 86             android:layout_height="wrap_content"
 87             android:text="" 
 88             android:textSize="25sp"/>
 89          <TextView
 90             android:id="@+id/tvTomWenduValue"
 91             android:layout_weight="2"
 92             android:layout_width="wrap_content"
 93             android:layout_height="wrap_content"
 94             android:text="" 
 95             android:textSize="25sp"/>
 96      </LinearLayout>
 97         
 98       <View
 99           android:layout_width="fill_parent"
100           android:layout_height="0.5dip"
101           android:background="#FF001100"/>
102  
103       <TextView
104         android:id="@+id/tvTodayType"
105         android:layout_width="fill_parent"
106         android:layout_height="wrap_content"
107         android:text="" 
108         android:textSize="25sp"/>  
109         
110       <View
111           android:layout_width="fill_parent"
112           android:layout_height="0.5dip"
113           android:background="#FF008800"/>  
114           
115       <TextView
116         android:id="@+id/tvTomorrowType"
117         android:layout_width="fill_parent"
118         android:layout_height="wrap_content"
119         android:text="" 
120         android:textSize="25sp"/>            
121 </LinearLayout>
View Code

到此,这个简单的天气程序基本上结束了。

整个项目需要下载,在此给出项目下载地址:http://pan.baidu.com/s/1gd3wcqJ

有什么问题尽管提出

原文地址:https://www.cnblogs.com/ouyangduoduo/p/4604314.html