天气预报App--基本功能实现

三、天气预报App基本功能实现
天气预报主要功能就是根据城市的代码,去动态获取当前的天气情况,并且将当前的选择的城市天气信息保存下来(Sharedpreferences).
1、获取JSon天气数据
2、根据android基础学习综合实例——天气预报App中分析的城市代码以及天气代码,保存到数据库中,再根据用户所选择的城市代码,获取对应的天气信息
3、特别注意,因为白天已经过去 ,预报在晚上那次更新的时候白天数据就会为空,即中国气象局的数据在晚上6点以后不会再更新白天的数据信息,在App中必须保存白天的天气信息。

3.1 城市代码数据库建立
(1)省份Province代码数据库:包括省份名称和代码

1
2
3
4
private static final String CREATE_PROVINCE = "create table Province ("
+ "id integer primary key autoincrement, "
+ "province_name text, "
+ "province_code text)";

添加对应的数据库操作
1)保存省份实例到数据库中

1
2
3
4
5
6
7
8
9
10
public void saveProvince(Province province)
{
if (province != null)
{
ContentValues values = new ContentValues();
values.put("province_name", province.getProvinceName());
values.put("province_code", province.getProvinceCode());
db.insert("Province", null, values);
}
}

2.在数据库中读取全国的所有省份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public List<Province> loadProvices()
{
List<Province> list = new ArrayList<Province>();
Cursor cursor = db
.query("Province", null, null, null, null, null, null);
if (cursor.moveToFirst())
{
do
{
Province province = new Province(); province.setId(cursor.getInt(cursor.getColumnIndex("id")));
province.setProvinceName(cursor.getString(cursor
.getColumnIndex("province_name")));
province.setProvinceCode(cursor.getString(cursor
.getColumnIndex("province_code")));
list.add(province);
} while (cursor.moveToNext());
}
return list;
}

(2)市级City代码数据库表建立

1
2
3
4
5
private static final String CREATE_CITY = "create table City ("
+ "id integer primary key autoincrement, "
+ "city_name text, "
+ "city_code text, "
+ "province_id integer)";

1.保存City信息到数据库中

1
2
3
4
5
6
7
8
9
10
11
public void saveCity(City city)
{
if (city != null)
{
ContentValues values = new ContentValues();
values.put("city_name", city.getCityName());
values.put("city_code", city.getCityCode());
values.put("province_id", city.getProvinceId());
db.insert("City", null, values);
}
}

2.根据用户所选的省份id,在数据库中读取对应的市级城市数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public List<City> loadCity(int provinceId)
{
List<City> list = new ArrayList<>();
Cursor cursor = db.query("City", null, "province_id = ?", new String[]
{ String.valueOf(provinceId) }, null, null, null);
if (cursor.moveToFirst())
{
do
{
City city = new City();
city.setId(cursor.getInt(cursor.getColumnIndex("id")));
city.setCityName(cursor.getString(cursor
.getColumnIndex("city_name")));
city.setCityCode(cursor.getString(cursor
.getColumnIndex("city_code")));
city.setProvinceId(provinceId);
list.add(city);
} while (cursor.moveToNext());
}
return list;
}

(3)县级County城市代码数据库建立

1
2
3
4
5
private static final String CREATE_COUNTY = "create table County ("
+ "id integer primary key autoincrement, "
+ "county_name text, "
+ "county_code text, "
+ "city_id integer)";

1.保存County信息到数据库中

1
2
3
4
5
6
7
8
9
10
11
12
public void saveCounty(County county)
{
if (county != null)
{
ContentValues values = new ContentValues();
values.put("county_name", county.getCountyName());
values.put("county_code", county.getCountyCode());
values.put("city_id", county.getCityId());
db.insert("County", null, values);
}
}

2.根据City的id在数据中获取对应的县城数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public List<County> loadCounties(int cityId)
{
List<County> list = new ArrayList<County>();
Cursor cursor = db.query("County", null, "city_id = ?", new String[]
{ String.valueOf(cityId) }, null, null, null);
if (cursor.moveToFirst())
{
do
{
County county = new County();
county.setCityId(cursor.getInt(cursor.getColumnIndex("id")));
county.setCountyName(cursor.getString(cursor
.getColumnIndex("county_name")));
county.setCountyCode(cursor.getString(cursor
.getColumnIndex("county_code")));
county.setCityId(cityId);
list.add(county);
} while (cursor.moveToNext());
}
return list;
}

3.2 根据城市代码在线获取城市的天气信息
因为中国气象局返回的数据是JSon格式的,所以我们通过解析JSon格式的数据,获得对应的天气信息。

(1)根据城市代码在线获取天气JSon数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public static void sendHttpRequest(final String address,
final HttpCallbackListener listener)
{
new Thread(new Runnable()
{
@Override
public void run()
{
HttpURLConnection connection = null;
URL url;
try
{
url = new URL(address);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(in,"UTF-8"));//这里用UTF-8是为了防止获取得到的JSON数据中出现中文而导致乱码
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
{
response.append(line);
}
if (listener != null)
{
// 回调onFinish()方法
listener.onFinish(response.toString());
}
in.close();
} catch (Exception e)
{
if (listener != null) {
// 回调onError()方法
listener.onError(e);
}
} finally{
if(connection != null){
connection.disconnect();
}
}
}
}).start();
}

其中listener是自定义的一个回调接口,通过回调接口可方便获得返回的天气信息response

1
2
3
4
5
public interface HttpCallbackListener
{
void onFinish(String response);
void onError(Exception e);
}

以上都是基本准备工作,本APP中主要包括2个Activity:ChooseAreaAcitvity和WeatherActivity。
3.3 ChooseAreaActivity:通过读取Excel获取城市的代码以及名称并显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public static String loadProvincesInfo(Context context,String xlsPath) throws IOException
{
if(xlsPath.equals("Area_Excel")){
StringBuilder provinceInfo= new StringBuilder();
try{
InputStream is = context.getAssets().open("areaid_v.xls");
//ileInputStream fileIn = new FileInputStream(xlsPath);
// 根据指定的文件输入流导入Excel从而产生Workbook对象
HSSFWorkbook wb0 = new HSSFWorkbook(is);
// 获取Excel文档中的第一个表单
HSSFSheet hssfSheet = wb0.getSheetAt(0);
// 对Sheet中的每一行进行迭代
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++)
{
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
// 如果当前行的行号(从0开始)未达到2(第三行)则从新循环
if (hssfRow != null)
{
// 创建实体类
HSSFCell no = hssfRow.getCell(0);
HSSFCell proname = hssfRow.getCell(6);
HSSFCell cityname = hssfRow.getCell(4);
HSSFCell countyname = hssfRow.getCell(2);
/*
* String subNo = getValue(no).substring(3, 5);//[3,5)
*/
//返回一行中的省市县的名称已经整个Number
String info = getValue(no) + "|" + getValue(proname) + "|"
+ getValue(cityname) + "|" + getValue(countyname) + ",";
provinceInfo.append(info);
}
}
/*fileIn.close();*/
is.close();
return provinceInfo.toString();
}catch(Exception e){
Log.d("TAG", "加载excel文件出错");
}
return provinceInfo.toString();
}else{
Log.d("TAG", "加载excel类型出错,应该为地区类型");
return null;
}
}