欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android天气预报app改进版

程序员文章站 2024-03-04 22:06:18
最近总是有人来和我说我以前写的一个小app无法正常获取数据~android简易版天气预报app 今天就又运行了下来查找问题,发现或许是接口有限制吧,不能在多台手机使用同...

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

最终效果图如下

Android天气预报app改进版 

工程图如下

Android天气预报app改进版

一、获取地区信息

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

Android天气预报app改进版

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

Android天气预报app改进版 

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

二、天气信息的获取

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

Android天气预报app改进版

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

 Android天气预报app改进版

三、数据库的设计

地区列表这些信息一般都是固定不变的,所以我们可以把第一次联网获取到的数据存进数据库里,下次再次访问时就从数据库里读取即可
首先要设定四个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的实现(改进版)

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