移动应用开发实践-Task12&13-输出天气信息的测试
目的
创建两种输出类(空气质量、天气预报)和它们的辅助类,直接做输出测试,看是否能通过url拿到json数据。
1.创建相关类
两个不同颜色的框对应两种输出类,其余为基础数据类型。主要也就是为了和json传过来的数据类型一一对应而已,不重要。
- Basic.java
package com.example.fyn_weather_task13_0.data;
import com.google.gson.annotations.SerializedName;
public class Basic {
public String cid;
public String location;
public String parent_city;
public String admin_area;
@SerializedName("cnty")
public String country;
// using @SerializedName("cnty") means the true tag in json is "cnty"
// which can be parsed as the value for country in Basic class
public String lat;
public String lon;
@SerializedName("tz")
public String timeZone;
@Override
public String toString() {
return "Basic{" +
"cid='" + cid + '\'' +
", location='" + location + '\'' +
", parent_city='" + parent_city + '\'' +
", admin_area='" + admin_area + '\'' +
", country='" + country + '\'' +
", lat='" + lat + '\'' +
", lon='" + lon + '\'' +
", timeZone='" + timeZone + '\'' +
'}';
}
}
- City.java
package com.example.fyn_weather_task13_0.data;
public class City {
private int id;
private String name;
private int parentId = -1;
private String enName = "";
private String initialName = "";
private String weather_id = "";
private int level = 0;
public City(int id, String name) {
this.id = id;
this.name = name;
}
public City(int id, int parentId, String enName) {
this.id = id;
this.parentId = parentId;
this.enName = enName;
}
public City(int id, String name, int parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
@Override
public String toString() {
return String.format("%s( %s )-id=%d", name, enName, id);
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
public String getWeather_id() {
return weather_id;
}
public void setWeather_id(String weather_id) {
this.weather_id = weather_id;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getEnName() {
return enName;
}
public void setEnName(String enName) {
this.enName = enName;
}
public String getInitialName() {
return initialName;
}
public void setInitialName(String initialName) {
this.initialName = initialName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- Now.java
package com.example.fyn_weather_task13_0.data;
import com.google.gson.annotations.SerializedName;
public class Now {
public String cloud;
public String cond_code;
public String cond_txt;
@SerializedName("fl")
public String feelingTemp;
@SerializedName("hum")
public String humidity;
@SerializedName("pcpn")
public String precipitation;
public String pres;
public String tmp;
@SerializedName("vis")
public String visibility;
public String wind_deg;
public String wind_dir;
@SerializedName("wind_sc")
public String windForce;
public String wind_spd;
@Override
public String toString() {
return "Now{" +
"cloud='" + cloud + '\'' +
", cond_code='" + cond_code + '\'' +
", cond_txt='" + cond_txt + '\'' +
", feelingTemp='" + feelingTemp + '\'' +
", humidity='" + humidity + '\'' +
", precipitation='" + precipitation + '\'' +
", pres='" + pres + '\'' +
", tmp='" + tmp + '\'' +
", visibility='" + visibility + '\'' +
", wind_deg='" + wind_deg + '\'' +
", wind_dir='" + wind_dir + '\'' +
", windForce='" + windForce + '\'' +
", wind_spd='" + wind_spd + '\'' +
'}';
}
}
- Update.java
package com.example.fyn_weather_task13_0.data;
public class Update {
public String loc;
public String utc;
@Override
public String toString() {
return "Update{" +
"loc='" + loc + '\'' +
", utc='" + utc + '\'' +
'}';
}
}
- DailyForecast.java
package com.example.fyn_weather_task13_0.data;
import com.google.gson.annotations.SerializedName;
public class DailyForecast {
public String cond_code_d;
public String cond_code_n;
public String cond_txt_d;
public String cond_txt_n;
public String date;
@SerializedName("hum")
public String humidity;
@SerializedName("mr")
public String moonRise;
@SerializedName("ms")
public String moonSet;
@SerializedName("pcpn")
public String precipitation;
@SerializedName("pop")
public String probability;
@SerializedName("pres")
public String pressure;
@SerializedName("sr")
public String sunRise;
@SerializedName("ss")
public String sunSet;
public String tmp_max;
public String tmp_min;
public String uv_index;
public String vis;
public String wind_deg;
public String wind_dir;
public String wind_sc;
public String wind_spd;
@Override
public String toString() {
return "DailyForecast{" +
"cond_code_d='" + cond_code_d + '\'' +
", cond_code_n='" + cond_code_n + '\'' +
", cond_txt_d='" + cond_txt_d + '\'' +
", cond_txt_n='" + cond_txt_n + '\'' +
", date='" + date + '\'' +
", humidity='" + humidity + '\'' +
", moonRise='" + moonRise + '\'' +
", moonSet='" + moonSet + '\'' +
", precipitation='" + precipitation + '\'' +
", probability='" + probability + '\'' +
", pressure='" + pressure + '\'' +
", sunRise='" + sunRise + '\'' +
", sunSet='" + sunSet + '\'' +
", tmp_max='" + tmp_max + '\'' +
", tmp_min='" + tmp_min + '\'' +
", uv_index='" + uv_index + '\'' +
", vis='" + vis + '\'' +
", wind_deg='" + wind_deg + '\'' +
", wind_dir='" + wind_dir + '\'' +
", wind_sc='" + wind_sc + '\'' +
", wind_spd='" + wind_spd + '\'' +
'}';
}
}
- WeatherForecast.java
package com.example.fyn_weather_task13_0.data;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class WeatherForecast {
public Basic basic;
public Update update;
public String status;
@SerializedName("daily_forecast")
public List<DailyForecast> dailyForecastList;
@Override
public String toString() {
return "WeatherForecast{" +
"basic=" + basic +
", update=" + update +
", status='" + status + '\'' +
", dailyForecastList=" + dailyForecastList +
'}';
}
}
- WeatherNow.java
package com.example.fyn_weather_task13_0.data;
public class WeatherNow {
public Basic basic;
public Update update;
public String status;
public Now now;
@Override
public String toString() {
return "WeatherNow{" +
"basic=" + basic +
", update=" + update +
", status='" + status + '\'' +
", now=" + now +
'}';
}
}
- AirNowCity.java
package com.example.fyn_weather_task13_0.data;
public class AirNowCity {
public String aqi;
public String qlty;
public String main;
public String pm25;
public String pm10;
public String no2;
public String so2;
public String co;
public String o3;
public String pub_time;
@Override
public String toString() {
return "AirNowCity{" +
"aqi='" + aqi + '\'' +
", qlty='" + qlty + '\'' +
", main='" + main + '\'' +
", pm25='" + pm25 + '\'' +
", pm10='" + pm10 + '\'' +
", no2='" + no2 + '\'' +
", so2='" + so2 + '\'' +
", co='" + co + '\'' +
", o3='" + o3 + '\'' +
", pub_time='" + pub_time + '\'' +
'}';
}
}
- AirNowStation.java
package com.example.fyn_weather_task13_0.data;
import com.google.gson.annotations.SerializedName;
public class AirNowStation {
@SerializedName("air_sta")
public String airStation;
public String aqi;
@SerializedName("asid")
public String airStationId;
public String co;
public String lat;
public String lon;
public String main;
public String no2;
public String o3;
public String pm10;
public String pm25;
public String pub_time;
public String qlty;
public String so2;
@Override
public String toString() {
return "AirNowStation{" +
"airStation='" + airStation + '\'' +
", aqi='" + aqi + '\'' +
", airStationId='" + airStationId + '\'' +
", co='" + co + '\'' +
", lat='" + lat + '\'' +
", lon='" + lon + '\'' +
", main='" + main + '\'' +
", no2='" + no2 + '\'' +
", o3='" + o3 + '\'' +
", pm10='" + pm10 + '\'' +
", pm25='" + pm25 + '\'' +
", pub_time='" + pub_time + '\'' +
", qlty='" + qlty + '\'' +
", so2='" + so2 + '\'' +
'}';
}
}
- AirQualityData.java
package com.example.fyn_weather_task13_0.data;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class AirQualityData {
public Basic basic;
public Update update;
public String status;
@SerializedName("air_now_city")
public AirNowCity airNowCity;
@SerializedName("air_now_station")
List<AirNowStation> airNowStationList;
@Override
public String toString() {
return "AirQualityData{" +
"basic=" + basic +
", update=" + update +
", status='" + status + '\'' +
", airNowCity=" + airNowCity +
", airNowStationList=" + airNowStationList +
'}';
}
}
2.配置工具类 WeatherApiUtil
三个接口应用在三个方法,第一个方法主要测试,后两个是实际使用的,都大同小异,看懂一个就可以了。
package com.example.fyn_weather_task13_0.utility;
import android.app.Activity;
import android.text.TextUtils;
import android.widget.Toast;
import com.example.fyn_weather_task13_0.data.AirQualityData;
import com.example.fyn_weather_task13_0.data.WeatherForecast;
import com.example.fyn_weather_task13_0.data.WeatherNow;
import com.google.gson.Gson;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class WeatherApiUtil {
public static final String API_KEY = "4a2a57d1114f42519d1073487b96308a";
public interface OnWeatherNowFinished {
public void onFinished(WeatherNow data);
}
public interface OnWeatherForecastFinished{
public void onFinished(WeatherForecast data);
}
public interface OnAirQualityFinished{
public void onFinished(AirQualityData data);
}
public static void getWeatherNow(final Activity activity, final String weather_id, final OnWeatherNowFinished listener) {
//https://free-api.heweather.net/s6/weather/now?location=cn101210701&key=4a2a57d1114f42519d1073487b96308a&lang=en
String url = String.format("https://free-api.heweather.net/s6/weather/now?location=%s&key=%s&lang=en", weather_id, API_KEY);
HttpUtil.getOkHttpAsync(activity, url, new HttpUtil.SimpleAsyncCall() {
@Override
public void onFailure(String e) {
showToast(activity, e);
listener.onFinished(null);
}
@Override
public void onResponse(String s) {
if (!TextUtils.isEmpty(s)) {
try {
JSONArray heWeather6 = new JSONObject(s).getJSONArray("HeWeather6");
String s1 = heWeather6.get(0).toString();
WeatherNow weatherNow = new Gson().fromJson(s1, WeatherNow.class);
if(weatherNow.status.equalsIgnoreCase("ok")){
weatherNow.now.tmp = weatherNow.now.tmp+"℃";
listener.onFinished(weatherNow);
}else {
listener.onFinished(null);
}
} catch (JSONException e) {
e.printStackTrace();
showToast(activity,e.toString());
listener.onFinished(null);
}
} else {
listener.onFinished(null);
}
}
});
}
public static void getWeatherForecast(final Activity activity, String weather_id, final OnWeatherForecastFinished listener){
String url=String.format("https://free-api.heweather.net/s6/weather/forecast?location=%s&key=%s&lang=en",weather_id,API_KEY);
HttpUtil.getOkHttpAsync(activity, url, new HttpUtil.SimpleAsyncCall() {
@Override
public void onFailure(String e) {
showToast(activity,e);
listener.onFinished(null);
}
@Override
public void onResponse(String response) {
if(!TextUtils.isEmpty(response)){
try {
JSONArray heWeather6 = new JSONObject(response).getJSONArray("HeWeather6");
String s= heWeather6.get(0).toString();
WeatherForecast data = new Gson().fromJson(s, WeatherForecast.class);
if(data!=null&&data.status.equalsIgnoreCase("ok")){
listener.onFinished(data);
return;
}
} catch (JSONException e) { e.printStackTrace(); }
}
listener.onFinished(null);
}
});
}
public static void getAirQualityData(final Activity activity, String weather_id, final OnAirQualityFinished listener){
String url=String.format("https://free-api.heweather.net/s6/air/now?location=%s&key=%s&lang=en",weather_id,API_KEY);
HttpUtil.getOkHttpAsync(activity, url, new HttpUtil.SimpleAsyncCall() {
@Override
public void onFailure(String e) {
showToast(activity,e);
listener.onFinished(null);
}
@Override
public void onResponse(String response) {
if(!TextUtils.isEmpty(response)){
try {
JSONArray heWeather6 = new JSONObject(response).getJSONArray("HeWeather6");
String s= heWeather6.get(0).toString();
AirQualityData data = new Gson().fromJson(s, AirQualityData.class);
if(data!=null&&data.status.equalsIgnoreCase("ok")){
listener.onFinished(data);
return;
}
} catch (JSONException e) {e.printStackTrace();}
}
listener.onFinished(null);
}
});
}
private static void showToast(Activity activity, String s) {
Toast.makeText(activity, s, Toast.LENGTH_SHORT).show();
}
}
3.WeatherActivity的实际调用
package com.example.fyn_weather_task13_0;
import ...
public class WeatherActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.weather_activity_main);
final EditText et = findViewById(R.id.weather_activity_et);
Button bt_test1 = findViewById(R.id.button_test1);
Button bt_test2 = findViewById(R.id.button_test2);
final TextView tv = findViewById(R.id.weather_activity_tv);
bt_test1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String weatherId = et.getText().toString().trim();
WeatherApiUtil.getWeatherForecast(WeatherActivity.this, weatherId, new WeatherApiUtil.OnWeatherForecastFinished() {
@Override
public void onFinished(WeatherForecast data) {
if (data!=null){
tv.setText(data.toString());
}else {
tv.setText("Fail to get data");
}
}
});
}
});
bt_test2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String weatherId = et.getText().toString().trim();
WeatherApiUtil.getAirQualityData(WeatherActivity.this, weatherId, new WeatherApiUtil.OnAirQualityFinished() {
@Override
public void onFinished(AirQualityData data) {
if (data!=null){
tv.setText(data.toString());
}else {
tv.setText("Fail to get data");
}
}
});
}
});
}
}
4.运行结果