工程图如下
一、获取地区信息
做这么一个天气预报app,首先就要获取到国内地区列表
(在我的另一篇博客有介绍:向任意网址发起数据请求)
中国天气网开放有天气预报接口,访问“http://www.weather.com.cn/data/list3/city.xml”就可以获取到国内省份列表以及其代号了
如果想要获取广东省下的城市列表,由上图可知广东省的代号为28,则接口地址是 “http://www.weather.com.cn/data/list3/city28.xml”,获取到的城市列表及代号如下:
依次类推还可以获取到更加详细的地区信息,这样就完成了开头部分
二、天气信息的获取
百度的APIStore拥有丰富的接口,涵盖了生活的许多方面。例如,我们就可以通过APIStore的某个接口获取到含有天气信息的JSON数据,从而实现天气预报功能
(在我的另一篇博客有介绍:获取含天气信息的JSON数据)
首先,使用者要有一个百度账号,然后登陆以下网址:中国和世界天气预报
该接口是免费的,不过因此也就不够稳定,我在调试的时候就经常出错
然后在API选项下点击“您自己的apikey”,查看自己的apikey。该值是每个开发者和app的唯一标识,需要妥善保管,有了apikey才可以进行下一步的操作
获取到的天气信息是JSON格式的,需要在程序中再来解析
三、数据库的设计
地区列表这些信息一般都是固定不变的,所以我们可以把第一次联网获取到的数据存进数据库里,下次再次访问时就从数据库里读取即可
首先要设定四个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; }}每小时天气预测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; }}然后,新建一个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) { }}然后,再建立一个WeatherDB类,用来进行实际的数据库操作,包括存取省份信息、城市信息、县信息等
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; }}四、联网操作
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(); }}五、工具类
public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e);}此外,使用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(); }}六、适配器
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <!-- 时间 --> <TextViewandroid:id="@+id/forecastTime"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2"android:gravity="center"android:textSize="20sp"android:textStyle="bold" /> <LinearLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="5"android:orientation="vertical"><!-- 温度 降水概率 --><LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="horizontal"> <!-- 温度 --> <TextViewandroid:id="@+id/forecastTemp"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center" /> <!-- 下雨概率 --> <TextViewandroid:id="@+id/forecastPop"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center" /></LinearLayout><!-- 风力 --><TextView android:id="@+id/forecastWind" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" /> </LinearLayout></LinearLayout>然后新建一个WeatherAdapter继承于ArrayAdapter< HourlyWeather>
public class WeatherAdapter extends ArrayAdapter<HourlyWeather> { private int resourceId; private Context context; public WeatherAdapter(Context context, int textViewResourceId, List<HourlyWeather> objects) {super(context, textViewResourceId, objects);this.context = context;this.resourceId = textViewResourceId; } public View getView(int position, View convertView, ViewGroup parent) {HourlyWeather weather = getItem(position);View view = LayoutInflater.from(context).inflate(resourceId, null);TextView forecastTime = (TextView) view.findViewById(R.id.forecastTime);TextView forecastTemp = (TextView) view.findViewById(R.id.forecastTemp);TextView forecastPop = (TextView) view.findViewById(R.id.forecastPop);TextView forecastWind = (TextView) view.findViewById(R.id.forecastWind);forecastTime.setText(weather.getTime());forecastTemp.setText(weather.getTemp());forecastPop.setText(weather.getPop());forecastWind.setText(weather.getWind());return view; }}七、Activity的编写
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"><TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textSize="24sp" /> </RelativeLayout> <ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>ChooseAreaActivity 需要完成的操作有:完成地区列表的加载、将选择的County名传递给WeatherActivity
public class ChooseAreaActivity extends AppCompatActivity { // 标记当前列表为省份 public static final int LEVEL_PROVINCE = 0; // 标记当前列表为城市 public static final int LEVEL_CITY = 1; // 标记当前列表为县 public static final int LEVEL_COUNTY = 2; // 进度对话框 private ProgressDialog progressDialog; // 标题栏 private TextView titleText; // 数据列表 private ListView listView; // 列表数据 private ArrayAdapter<String> adapter; // 数据库 private WeatherDB weatherDB; private List<String> dataList; private List<Province> provinceList; private List<City> cityList; private List<County> countyList; //选择的省份 private Province selectedProvince; //选择的城市 private City selectedCity; //当前选择的列表类型 private int currentLevel; //标记是否从WeatherActivity跳转而来的 private boolean isFromWeatherActivity; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);isFromWeatherActivity = getIntent().getBooleanExtra("ChooseArea", false);SharedPreferences sharedPreferences = getSharedPreferences("Weather", Context.MODE_PRIVATE);// 如果country已选择且本Activity不是从天气界面启动而来的,则直接跳转到WeatherActivityif (!TextUtils.isEmpty(sharedPreferences.getString("CountyName", "")) && !isFromWeatherActivity) { Intent intent = new Intent(this, WeatherActivity.class); startActivity(intent); finish(); return;}setContentView(R.layout.activity_choose_area);if (getSupportActionBar() != null) { getSupportActionBar().hide();}listView = (ListView) findViewById(R.id.listView);titleText = (TextView) findViewById(R.id.title);dataList = new ArrayList<>();adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);listView.setAdapter(adapter);weatherDB = WeatherDB.getInstance(this);listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {if (currentLevel == LEVEL_PROVINCE) { selectedProvince = provinceList.get(index); queryCities();} else if (currentLevel == LEVEL_CITY) { selectedCity = cityList.get(index); queryCounties();} else if (currentLevel == LEVEL_COUNTY) { //当点击到县列表时,就利用Intent跳转到天气信息界面 String countyName = countyList.get(index).getCountyName(); Intent intent = new Intent(ChooseAreaActivity.this, WeatherActivity.class); intent.putExtra("CountyName", countyName); startActivity(intent); finish();} }});queryProvinces(); } private void queryProvinces() {showProgressDialog();provinceList = weatherDB.getAllProvince();if (provinceList.size() > 0) { dataList.clear(); for (Province province : provinceList) {dataList.add(province.getProvinceName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText("中国"); currentLevel = LEVEL_PROVINCE; closeProgressDialog();} else { queryFromServer(null, "province");} } private void queryCities() {showProgressDialog();cityList = weatherDB.getAllCity(selectedProvince.getProvinceId());if (cityList.size() > 0) { dataList.clear(); for (City city : cityList) {dataList.add(city.getCityName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText(selectedProvince.getProvinceName()); currentLevel = LEVEL_CITY; closeProgressDialog();} else { queryFromServer(selectedProvince.getProvinceId(), "city");} } private void queryCounties() {showProgressDialog();countyList = weatherDB.getAllCountry(selectedCity.getCityId());if (countyList.size() > 0) { dataList.clear(); for (County county : countyList) {dataList.add(county.getCountyName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText(selectedCity.getCityName()); currentLevel = LEVEL_COUNTY; closeProgressDialog();} else { queryFromServer(selectedCity.getCityId(), "county");} } private void queryFromServer(final String code, final String type) {String address;// code不为空if (!TextUtils.isEmpty(code)) { address = "http://www.weather.com.cn/data/list3/city" + code + ".xml";} else { address = "http://www.weather.com.cn/data/list3/city.xml";}HttpUtil.sendHttpRequest(address, new HttpCallbackListener() { @Override public void onFinish(String response) {boolean result = false;if ("province".equals(type)) { result = Utility.saveProvincesResponse(weatherDB, response);} else if ("city".equals(type)) { result = Utility.saveCitiesResponse(weatherDB, response, selectedProvince.getProvinceId());} else if ("county".equals(type)) { result = Utility.saveCountiesResponse(weatherDB, response, selectedCity.getCityId());}if (result) { runOnUiThread(new Runnable() {@Overridepublic void run() { if ("province".equals(type)) {queryProvinces(); } else if ("city".equals(type)) {queryCities(); } else if ("county".equals(type)) {queryCounties(); }} });} } @Override public void onError(Exception e) {runOnUiThread(new Runnable() { @Override public void run() {Toast.makeText(ChooseAreaActivity.this, "加载失败", Toast.LENGTH_SHORT).show(); }}); }});closeProgressDialog(); } private void showProgressDialog() {if (progressDialog == null) { progressDialog = new ProgressDialog(this); progressDialog.setMessage("正在加载……"); progressDialog.setCanceledOnTouchOutside(false);}progressDialog.show(); } private void closeProgressDialog() {if (progressDialog != null) { progressDialog.dismiss();} } @Override public void onBackPressed() {if (currentLevel == LEVEL_COUNTY) { queryCities();} else if (currentLevel == LEVEL_CITY) { queryProvinces();} else { if (isFromWeatherActivity) {Intent intent = new Intent(this, WeatherActivity.class);startActivity(intent); } finish();} }}WeatherActivity的布局相对复杂些,包含了许多个TextView,我也只是想着简单就好,就简单地把数据用文本呈现出来
// 城市切换按钮 private Button citySwitch; // 刷新数据按钮 private Button weatherRefresh; // 城市名 private TextView cityName; // 白天夜晚天气描叙 private TextView DayNightWeather; // 温度 private TextView temp; // 日出时间 private TextView sunriseTime; // 日落时间 private TextView sunsetTime; // 风力 private TextView wind; // 降水概率 private TextView pop; // 发布时间 private TextView updateTime; // 今日天气预测列表 private ListView listview; public static List<HourlyWeather> weatherList = new ArrayList<>(); private SharedPreferences sharedPreferences; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.weather);if (getSupportActionBar() != null) { getSupportActionBar().hide();}init(); } private void init() {citySwitch = (Button) findViewById(R.id.citySwitch);weatherRefresh = (Button) findViewById(R.id.weatherRefresh);citySwitch.setOnClickListener(this);weatherRefresh.setOnClickListener(this);cityName = (TextView) findViewById(R.id.cityName);DayNightWeather = (TextView) findViewById(R.id.DayNightWeather);temp = (TextView) findViewById(R.id.temp);sunriseTime = (TextView) findViewById(R.id.sunriseTime);sunsetTime = (TextView) findViewById(R.id.sunsetTime);wind = (TextView) findViewById(R.id.wind);pop = (TextView) findViewById(R.id.pop);updateTime = (TextView) findViewById(R.id.updateTime);listview = (ListView) findViewById(R.id.hourlyForecast);sharedPreferences = getSharedPreferences("Weather", Context.MODE_PRIVATE);String countyName = getIntent().getStringExtra("CountyName");// 当countyName不为空if (!TextUtils.isEmpty(countyName)) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("CountyName", countyName); editor.commit();} else { countyName = sharedPreferences.getString("CountyName", "");}weatherRefresh.setText("同步中……");queryFromServer(countyName); } @Override public void onClick(View view) {switch (view.getId()) { case R.id.citySwitch:Intent intent = new Intent(this, ChooseAreaActivity.class);intent.putExtra("ChooseArea", true);startActivity(intent);finish();break; case R.id.weatherRefresh:weatherRefresh.setText("同步中……");String countyName = sharedPreferences.getString("CountyName", "");if (!TextUtils.isEmpty(countyName)) { queryFromServer(countyName);}break;} } private void queryFromServer(final String countyName) {try { String url = "http://apis.baidu.com/heweather/weather/free?city="; String name = new String(countyName.getBytes("UTF-8"), "iso-8859-1"); HttpUtil.sendHttpRequest(url + name, new HttpCallbackListener() {@Overridepublic void onFinish(String response) { Utility.handleWeatherResponse(WeatherActivity.this, response); runOnUiThread(new Runnable() {@Overridepublic void run() { showWeather();} });}@Overridepublic void onError(Exception e) { runOnUiThread(new Runnable() {@Overridepublic void run() { Toast.makeText(WeatherActivity.this, "同步失败", Toast.LENGTH_LONG).show(); weatherRefresh.setText("更新数据");} });} });} catch (Exception e) { e.printStackTrace();} } private void showWeather() {cityName.setText(sharedPreferences.getString("cityName", "未知"));sunriseTime.setText("日出:" + sharedPreferences.getString("sunriseTime", "未知"));sunsetTime.setText("日落:" + sharedPreferences.getString("sunsetTime", "未知"));DayNightWeather.setText("日:" + sharedPreferences.getString("dayWeather", "未知") + " 夜:" + sharedPreferences.getString("nightWeather", "未知"));temp.setText("温度:" + sharedPreferences.getString("temp", "未知"));wind.setText("风力:" + sharedPreferences.getString("wind", "未知"));pop.setText("降水概率:" + sharedPreferences.getString("pop", "未知"));updateTime.setText("发布时间:" + sharedPreferences.getString("updateTime", "未知"));WeatherAdapter adapter = new WeatherAdapter(this, R.layout.hourly_weather, weatherList);listview.setAdapter(adapter);Toast.makeText(WeatherActivity.this, "已经是最新数据了", Toast.LENGTH_SHORT).show();weatherRefresh.setText("更新数据"); }}八、说明