天气预报的实现

地区列表这些信息一般都是固定不变的,所以我们可以把第一次联网获取到的数据存进数据库里,下次再次访问时就从数据库里读取即可 
首先要设定四个Model,包括:省份、城市、县、每小时天气预测,用来承载数据 
每个Model包括几个属性以及相应的get和set方法 
例如,省份Province的设计如下所示,城市City和县County的设计类似

/**
 * 省份
 */
public class Province {
    //省份名
    private String provinceName;
    //省份ID
    private String provinceId;

    public String getProvinceId() {
        return provinceId;
    }

    public String getProvinceName() {
        return provinceName;
    }

    public void setProvinceId(String provinceId) {
        this.provinceId = provinceId;
    }

    public void setProvinceName(String provinceName) {
        this.provinceName = provinceName;
    }
}
 
 
  • 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
  • 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

每小时天气预测HourlyWeather的设计如下:

/**
 * Created by ZY on 2016/7/21.
 */
public class HourlyWeather {

    //预测时间
    private String time;
    //温度
    private String temp;
    //降水概率
    private String pop;
    //风力
    private String wind;

    public HourlyWeather(String time, String temp, String pop, String wind) {
        this.time = time;
        this.temp = temp;
        this.pop = pop;
        this.wind = wind;
    }

    public String getTime() {
        return time;
    }

    public String getTemp() {
        return temp;
    }

    public String getPop() {
        return pop;
    }

    public String getWind() {
        return wind;
    }
}
 
 
  • 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
  • 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

然后,新建一个DatabaseHelper类继承于SQLiteOpenHelper,用来建立三个数据库表

public class DatabaseHelper extends SQLiteOpenHelper {

    private final String CREATE_PROVINCE = "create table Province ("
            + "provinceName text," + "provinceId text )";

    private final String CREATE_CITY = "create table City("
            + "cityName text," + "cityId text," + "provinceId text)";

    private final String CREATE_COUNTY = "create table County("
            + "countyName text," + "countyId text," + "cityId text)";

    public DatabaseHelper(Context context, String DbName,
                          CursorFactory factory, int version) {
        super(context, DbName, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_PROVINCE);
        db.execSQL(CREATE_CITY);
        db.execSQL(CREATE_COUNTY);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}
 
 
  • 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
  • 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

然后,再建立一个WeatherDB类,用来进行实际的数据库操作,包括存取省份信息、城市信息、县信息等 
需要注意的是,因为每个城市都是包含在某个省份下的,所以查询某个省份下的所有城市列表,需要将省份的ID传入作为唯一标识

public class WeatherDB {

    private final String DataBaseName = "ZyWeather";

    private final int VERSION = 1;

    private SQLiteDatabase database;

    private static WeatherDB weatherDB;

    private WeatherDB(Context context) {
        DatabaseHelper dataBaseHelper = new DatabaseHelper(context,
                DataBaseName, null, VERSION);
        database = dataBaseHelper.getWritableDatabase();
    }

    //获取实例
    public static WeatherDB getInstance(Context context) {
        if (weatherDB == null) {
            weatherDB = new WeatherDB(context);
        }
        return weatherDB;
    }

    //保存省份信息
    public void saveProvinces(List<Province> provinceList) {
        if (provinceList != null && provinceList.size() > 0) {
            ContentValues values = new ContentValues();
            for (int i = 0; i < provinceList.size(); i++) {
                values.put("provinceName", provinceList.get(i).getProvinceName());
                values.put("provinceId", provinceList.get(i).getProvinceId());
                database.insert("Province", null, values);
                values.clear();
            }
        }
    }

    //保存城市信息
    public void saveCities(List<City> cityList) {
        if (cityList != null && cityList.size() > 0) {
            ContentValues values = new ContentValues();
            for (int i = 0; i < cityList.size(); i++) {
                values.put("cityName", cityList.get(i).getCityName());
                values.put("cityId", cityList.get(i).getCityId());
                values.put("provinceId", cityList.get(i).getProvinceId());
                database.insert("City", null, values);
                values.clear();
            }
        }
    }

    //保存乡村信息
    public void saveCounties(List<County> countyList) {
        if (countyList != null && countyList.size() > 0) {
            ContentValues values = new ContentValues();
            for (int i = 0; i < countyList.size(); i++) {
                values.put("countyName", countyList.get(i).getCountyName());
                values.put("countyId", countyList.get(i).getCountyId());
                values.put("cityId", countyList.get(i).getCityId());
                database.insert("County", null, values);
                values.clear();
            }
        }
    }

    //返回所有省份信息
    public List<Province> getAllProvince() {
        Cursor cursor = database.query("Province", null, null, null, null, null, null);
        List<Province> list = new ArrayList<>();
        Province province;
        if (cursor.moveToFirst()) {
            do {
                province = new Province();
                province.setProvinceName(cursor.getString(cursor.getColumnIndex("provinceName")));
                province.setProvinceId(cursor.getString(cursor.getColumnIndex("provinceId")));
                list.add(province);
            } while (cursor.moveToNext());
        }
        return list;
    }

    //返回指定省份下的所有城市
    public List<City> getAllCity(String provinceId) {
        List<City> list = new ArrayList<>();
        City city;
        Cursor cursor = database.query("City", null, "provinceId = ?", new String[]{provinceId}, null, null, null);
        if (cursor.moveToFirst()) {
            do {
                city = new City();
                city.setCityName(cursor.getString(cursor.getColumnIndex("cityName")));
                city.setCityId(cursor.getString(cursor.getColumnIndex("cityId")));
                city.setProvinceId(provinceId);
                list.add(city);
            } while (cursor.moveToNext());
        }
        return list;
    }

    //返回指定城市下的所有乡村
    public List<County> getAllCountry(String cityId) {
        List<County> list = new ArrayList<>();
        Cursor cursor = database.query("County", null, "cityId=?", new String[]{cityId}, null, null, null);
        County county;
        if (cursor.moveToFirst()) {
            do {
                county = new County();
                county.setCountyName(cursor.getString(cursor.getColumnIndex("countyName")));
                county.setCountyId(cursor.getString(cursor.getColumnIndex("countyId")));
                county.setCityId(cityId);
                list.add(county);
            } while (cursor.moveToNext());
        }
        return list;
    }

}
 
 
  • 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
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 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
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

四、联网操作

整个app用同一个函数来完成各种数据数据操作,该函数包含在HttpUtil类下,为静态函数 
当中需要填入自己申请的apikey,该key仅在获取天气信息时有用,在获取地区信息时是不需要的,这里只是为了简便,所以就一起写上了

public class HttpUtil {

    public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
            public void run() {
                HttpURLConnection connection = null;
                try {
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setRequestProperty("apikey", "填入自己的apikey");
                    connection.connect();
                    InputStream inputStream = connection.getInputStream();
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        response.append(line);
                    }
                    if (listener != null) {
                        listener.onFinish(response.toString());
                    }
                } catch (Exception e) {
                    if (listener != null) {
                        listener.onError(e);
                    }
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
}
 
 
  • 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
  • 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

五、工具类

在联网访问数据成功或失败后,都需要通过回调方法进行数据处理,所以需要设定一个接口HttpCallbackListener

public interface HttpCallbackListener {

    void onFinish(String response);

    void onError(Exception e);

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

此外,使用HttpUtil 类获取到地区信息后,因为数据包含一些分隔符,无法直接存入数据库,而且获取到的天气信息也是JSON格式的,也需要进行数据解析,所以还需要有一个Utility类用来进行数据处理

public class Utility {

    // 保存服务器返回的省级数据
    public static boolean saveProvincesResponse(WeatherDB weatherDB, String response) {
        if (!TextUtils.isEmpty(response)) {
            String[] allProvinces = response.split(",");
            if (allProvinces != null && allProvinces.length > 0) {
                Province province;
                List<Province> provinceList = new ArrayList<>();
                for (String p : allProvinces) {
                    String[] array = p.split("\\|");
                    province = new Province();
                    province.setProvinceId(array[0]);
                    province.setProvinceName(array[1]);
                    provinceList.add(province);
                }
                weatherDB.saveProvinces(provinceList);
                return true;
            }
        }
        return false;
    }

    // 保存服务器返回的市级数据
    public static boolean saveCitiesResponse(WeatherDB weatherDB, String response, String provinceId) {
        if (!TextUtils.isEmpty(response)) {
            String[] allCities = response.split(",");
            if (allCities != null && allCities.length > 0) {
                City city;
                List<City> cityList = new ArrayList<>();
                for (String c : allCities) {
                    String[] array = c.split("\\|");
                    city = new City();
                    city.setCityId(array[0]);
                    city.setCityName(array[1]);
                    city.setProvinceId(provinceId);
                    cityList.add(city);
                }
                weatherDB.saveCities(cityList);
                return true;
            }
        }
        return false;
    }

    // 保存服务器返回的县级数据
    public static boolean saveCountiesResponse(WeatherDB weatherDB, String response, String cityId) {
        if (!TextUtils.isEmpty(response)) {
            String[] allCounties = response.split(",");
            if (allCounties != null && allCounties.length > 0) {
                County county;
                List<County> countyList = new ArrayList<>();
                for (String c : allCounties) {
                    String[] array = c.split("\\|");
                    county = new County();
                    county.setCountyId(array[0]);
                    county.setCountyName(array[1]);
                    county.setCityId(cityId);
                    countyList.add(county);
                }
                weatherDB.saveCounties(countyList);
                return true;
            }
        }
        return false;
    }

    // 处理服务器返回的json数据
    public static void handleWeatherResponse(Context context, String response) {
        try {
            JSONObject jsonobject = new JSONObject(response);
            JSONArray title = jsonobject.getJSONArray("HeWeather data service 3.0");
            JSONObject first_object = (JSONObject) title.get(0);

            JSONObject basic = (JSONObject) first_object.get("basic");

            //更新时间
            JSONObject update = (JSONObject) basic.get("update");
            JSONArray daily_forecast = (JSONArray) first_object.get("daily_forecast");
            JSONObject daily_forecast_first = (JSONObject) daily_forecast.get(0);
            JSONObject cond = (JSONObject) daily_forecast_first.get("cond");
            //温度
            JSONObject temp = (JSONObject) daily_forecast_first.get("tmp");

            JSONObject astro = (JSONObject) daily_forecast_first.get("astro");

            JSONObject wind = (JSONObject) daily_forecast_first.get("wind");

            JSONArray hourly_forecast = (JSONArray) first_object.get("hourly_forecast");

            WeatherActivity.weatherList.clear();

            for (int i = 0; i < hourly_forecast.length(); i++) {
                JSONObject json = hourly_forecast.getJSONObject(i);
                JSONObject json_wind = (JSONObject) json.get("wind");
                String date = json.getString("date");
                String[] array = date.split(" ");
                String dir = json_wind.getString("dir");
                String sc = json_wind.getString("sc");
                String hourly_clock = array[1];
                String hourly_temp = "温度:" + json.getString("tmp") + "℃";
                String hourly_pop = "降水概率:" + json.getString("pop");
                String hourly_wind = "风力:" + dir + " " + sc + "级";
                HourlyWeather weather = new HourlyWeather(hourly_clock, hourly_temp, hourly_pop, hourly_wind);
                WeatherActivity.weatherList.add(weather);
            }
            //日出
            String sunriseTime = astro.getString("sr");
            //日落
            String sunsetTime = astro.getString("ss");
            //白天天气
            String dayWeather = cond.getString("txt_d");
            //夜晚天气
            String nightWeather = cond.getString("txt_n");
            //风力
            String windText = wind.getString("dir") + " " + wind.getString("sc") + "级";
            //降水概率
            String pop = daily_forecast_first.getString("pop");
            //温度
            String tempText = temp.getString("min") + "℃~" + temp.getString("max") + "℃";
            //更新时间
            String updateTime = update.getString("loc");
            //城市名
            String cityName = basic.getString("city");
            saveWeatherInfo(context, cityName, sunriseTime, sunsetTime, dayWeather, nightWeather, windText, pop, tempText, updateTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void saveWeatherInfo(Context context, String cityName,
                                        String sunriseTime, String sunsetTime, String dayWeather, String nightWeather,
                                        String windText, String pop, String tempText, String updateTime) {
        SharedPreferences.Editor editor = context.getSharedPreferences("Weather", Context.MODE_PRIVATE).edit();
        editor.putString("cityName", cityName);
        editor.putString("sunriseTime", sunriseTime);
        editor.putString("sunsetTime", sunsetTime);
        editor.putString("dayWeather", dayWeather);
        editor.putString("nightWeather", nightWeather);
        editor.putString("wind", windText);
        editor.putString("pop", pop);
        editor.putString("temp", tempText);
        editor.putString("updateTime", updateTime);
        editor.commit();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值