Android天气预报app改进版

Android天气预报app改进版,第1张

概述最近总是有人来和我说我以前写的一个小app无法正常获取数据~Android简易版天气预报app

最近总是有人来和我说我以前写的一个小app无法正常获取数据~AndroID简易版天气预报app
今天就又运行了下来查找问题,发现或许是接口有限制吧,不能在多台手机使用同个APIkey
然后,发现了我写的代码实在乱七八糟,界面也实在不好看,就又重写了一遍,小小地修改了一遍,开发环境改为了AndroID Studio

最终效果图如下

 

工程图如下

一、获取地区信息@H_502_24@

做这么一个天气预报app,首先就要获取到国内地区列表
(在我的另一篇博客有介绍:向任意网址发起数据请求)
中国天气网开放有天气预报接口,访问“http://www.weather.com.cn/data/List3/city.xml”就可以获取到国内省份列表以及其代号了

如果想要获取广东省下的城市列表,由上图可知广东省的代号为28,则接口地址是 “http://www.weather.com.cn/data/List3/city28.xml”,获取到的城市列表及代号如下:

 

依次类推还可以获取到更加详细的地区信息,这样就完成了开头部分

二、天气信息的获取@H_502_24@

百度的APIStore拥有丰富的接口,涵盖了生活的许多方面。例如,我们就可以通过APIStore的某个接口获取到含有天气信息的JsON数据,从而实现天气预报功能
(在我的另一篇博客有介绍:获取含天气信息的JsON数据)
首先,使用者要有一个百度账号,然后登陆以下网址:中国和世界天气预报
该接口是免费的,不过因此也就不够稳定,我在调试的时候就经常出错
然后在API选项下点击“您自己的APIkey”,查看自己的APIkey。该值是每个开发者和app的唯一标识,需要妥善保管,有了APIkey才可以进行下一步的 *** 作

获取到的天气信息是JsON格式的,需要在程序中再来解析

 

三、数据库的设计@H_502_24@

地区列表这些信息一般都是固定不变的,所以我们可以把第一次联网获取到的数据存进数据库里,下次再次访问时就从数据库里读取即可
首先要设定四个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类,用来进行实际的数据库 *** 作,包括存取省份信息、城市信息、县信息等
需要注意的是,因为每个城市都是包含在某个省份下的,所以查询某个省份下的所有城市列表,需要将省份的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",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",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",values);    values.clear();   }  } } //返回所有省份信息 public List<Province> getAllProvince() {  Cursor cursor = database.query("Province",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","provinceID = ?",new String[]{provinceID},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","cityID=?",new String[]{cityID},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; }}

四、联网 *** 作@H_502_24@

整个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(); }}

五、工具类@H_502_24@

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

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 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 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(); }}

 六、适配器
@H_502_24@由上边的动态图可以看到每小时的天气预测信息,那是使用ListVIEw呈现的,这就要为其提供一个适配器了
ListVIEw使用的布局文件如下:

<?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"> <!-- 时间 --> <TextVIEw  androID: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" /> <linearLayout  androID: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">   <!-- 温度 -->   <TextVIEw    androID:ID="@+ID/forecastTemp"    androID:layout_wIDth="0dp"    androID:layout_height="match_parent"    androID:layout_weight="1"    androID:gravity="center" />   <!-- 下雨概率 -->   <TextVIEw    androID: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>
只要重写getVIEw(int position,VIEw convertVIEw,VIEwGroup parent)方法即可

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,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的编写
@H_502_24@首先要完成地区选择界面ChooseAreaActivity
ChooseAreaActivity的界面仅包括一个居中的TextVIEw和一个ListVIEw
布局文件如下:

<?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"> <relativeLayout  androID: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> <ListVIEw  androID:ID="@+ID/ListVIEw"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent" /></linearLayout>

ChooseAreaActivity 需要完成的 *** 作有:完成地区列表的加载、将选择的County名传递给WeatherActivity
此外,当中使用了showProgressDialog()来呈现一个进度对话框,也设为无法通过返回键关闭,而我又没有在弱网环境下调试过,每次加载都是很快,也没见到对话框出来过,所以也不知道showProgressDialog()到底有没有BUG啥的~

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不是从天气界面启动而来的,则直接跳转到WeatherActivity  if (!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,selectedCity.getCityID());    }    if (result) {     runOnUiThread(new Runnable() {      @OverrIDe      public 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() {    @OverrIDe    public voID onFinish(String response) {     Utility.handleWeatherResponse(WeatherActivity.this,response);     runOnUiThread(new Runnable() {      @OverrIDe      public voID run() {       showWeather();      }     });    }    @OverrIDe    public voID onError(Exception e) {     runOnUiThread(new Runnable() {      @OverrIDe      public 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("更新数据"); }}

八、说明 @H_502_24@
很奇怪的是,这个小app在我的4.4版本的小米手机上运行无误,可在5.1系统的模拟器和华为手机上却提示无法获取到数据,返回的JsON数据提示说城市未知,查看了很久也没搞明白,只能作罢~~

代码下载地址:Android简易版天气预报app的实现(改进版)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android天气预报app改进版全部内容,希望文章能够帮你解决Android天气预报app改进版所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1148814.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存