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 + "\n" +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 + "\n" +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

有什么問題盡管提出


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM