最近总是有人来和我说我以前写的一个小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改进版所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)