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 }

以下是这个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>

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

第三步:将获得省份名字以及城市编号 与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 }

得到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 }

获得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 }

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

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

此界面也相对比较简单:

  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>

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

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

有什么问题尽管提出

时间: 2024-08-08 06:56:03

Android学习之天气预报简单版的相关文章

Android学习之路——简易版微信为例(二)

1 概述 从这篇博文开始,正式进入简易版微信的开发.深入学习前,想谈谈个人对Android程序开发一些理解,不一定正确,只是自己的一点想法.Android程序开发不像我们在大学时候写C控制台程序那样,需要从main开始写代码逻辑,大部分逻辑控制代码都由自己来实现.事实上,Android已经为我们提供了一个程序运行的框架,我们只需要往框架中填入我们所需的内容即可,这里的内容主要是:四大组件——Activity.Service.ContentProvider.BroadCast.在这四大组件中,可以

Android学习之路——简易版微信为例(三)

最近好久没有更新博文,一则是因为公司最近比较忙,另外自己在Android学习过程和简易版微信的开发过程中碰到了一些绊脚石,所以最近一直在学习充电中.下面来列举一下自己所走过的弯路: (1)本来打算前端(即客户端)和后端(即服务端)都由自己实现,后来发现服务端已经有成熟的程序可以使用,如基于XMPP协议的OpenFire服务器程序:客户端也已经有成熟的框架供我们使用,如Smack,同样基于XMPP协议.这一系列笔记式文章主要是记录自己学习Android开发的过程,为突出重点(Android的学习)

android学习ViewPager的简单使用

使用ViewPager需要引入android.support.v4.View.ViewPager这样的jar包,谷歌公司为解决当前版本碎片化的问题,提供的兼容的包.主要目的就是解决向下兼容问题. 1,加载显示的页卡 将layout布局转换成view对象 (1)LayoutInflater if= getLayoutInflater().from(this); if.inflater(resource,root); (2) View.inflate(context,resource,root);

android学习ProgressBar的简单使用

android 提供的ProgressBar控件分为两种,一种是不带进度的进度条,一种是带进度的进度条,如果可以计算任务的完成量那么就用带进度条的,如果无法计算任务量,那么就使用不带进度的进度条.ProgressBar如果说只使用系统提供的,那就很简单,就只有那些属性方法,但是感觉比较难得就是ProgressBar的样式,一般做应用都不会直接使用系统提供的,而是在它的额基础上做进一步的美化. ProgressBar的关键属性 android:max 最大值 android:proress 第一进

[Android学习笔记]Context简单理解

一.Context是什么?上下文对象,可以理解为一个程序的运行的环境,从中可以获取当前程序的资源:getResources,getAssets 二.常见的Context有哪些?Application ContextActivity ContextService Context当创建一个Application , Activity, Service 的时候,都会对应创建一个属于他们的Context对象虽然同一个应用中的不同Context获取到的资源是同一套,环境是同一个,但是他们的生命周期不一致,

Android 学习资料分享(2015 版)

我是如何自学Android,资料分享(2015 版) Tikitoo2015.02.11 10:21 1713 字 3932 次阅读 自己学了两三个月的Android,最近花了一周左右的时间写了个App--Diigoer(已开源),又花了一两周时间找工作,收到了两个Offer,也算是对自己学习的一种认可吧:我刚开始学习总结的--<我是如何自学Android,资料分享>,如果是初学Android 的话,不应该错过的,而今天这篇分享好这篇文章,相对于第一次写的会有所提升,所以建议先把上一篇看了,再

【资源】Android学习资料 - 逆天整理 - 精华无密版

 入门看视频,提高看书籍,飘升做项目.老练研开源,高手读外文,大牛讲低调~  极客学院安卓Android全套最新视频教程[17G全套视频+独家源码] http://pan.baidu.com/s/1kT5nSkn 链接: http://pan.baidu.com/s/1jGsyJ0y 密码: btbg 传智播客Java安卓方向就业班全套视频下载 http://pan.baidu.com/s/1eQq4YXG 链接: http://pan.baidu.com/s/1qWA3yyS 密码: p7qj

Android学习Scroller(三)——控件平移划过屏幕 (Scroller简单使用)

MainActivity如下: package cc.cn; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; /** * Demo描述: * Scroller使用示例--让控件平移划过屏幕 * * 参考资料: * http://blog.cs

Android学习笔记(二十):回归简单的ListView

在之前连续对ListVew作了逐步深入的探讨,对于手持屏幕来讲,其实可以比较简单,如果别人愿意付钱,不在乎将代码再些一次,这是客户端的开发和复杂服务器的开发不同的地方.当然各人有各人的看法.绝大部分情况下,一个list元素可能左右各有一个widget就差不多,回归简约风格,这也是小尺寸屏幕和手指操作的特点. 在数据的传递,Java里面,具有<Key,Value>的Hash是非常重要的,可以方便增/删/改/查,如果我们不使用数据库存储,或者将数据存放在内存中,<Key,Value>是