Android天气预报app改进版
最近总是有人来和我说我以前写的一个小app无法正常获取数据~android简易版天气预报app
今天就又运行了下来查找问题,发现或许是接口有限制吧,不能在多台手机使用同个apikey
然后,发现了我写的代码实在乱七八糟,界面也实在不好看,就又重写了一遍,小小地修改了一遍,开发环境改为了android studio
最终效果图如下
工程图如下
一、获取地区信息
做这么一个天气预报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类,用来进行实际的数据库操作,包括存取省份信息、城市信息、县信息等
需要注意的是,因为每个城市都是包含在某个省份下的,所以查询某个省份下的所有城市列表,需要将省份的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; } }
四、联网操作
整个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(); } }
五、工具类
在联网访问数据成功或失败后,都需要通过回调方法进行数据处理,所以需要设定一个接口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 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(); } }
六、适配器
由上边的动态图可以看到每小时的天气预测信息,那是使用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, 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的编写
首先要完成地区选择界面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, response, 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("更新数据"); } }
八、说明
很奇怪的是,这个小app在我的4.4版本的小米手机上运行无误,可在5.1系统的模拟器和华为手机上却提示无法获取到数据,返回的json数据提示说城市未知,查看了很久也没搞明白,只能作罢~~
代码下载地址:android简易版天气预报app的实现(改进版)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。