この JSON からデータを取得する方法を理解するのに非常に苦労しています。
{
data: {
current_condition: [
{
cloudcover: "100",
humidity: "74",
observation_time: "06:53 PM",
precipMM: "4.5",
pressure: "1009",
temp_C: "26",
temp_F: "79",
visibility: "16",
weatherCode: "356",
weatherDesc: [
{
value: "Moderate or heavy rain shower"
}
] ,
weatherIconUrl: [
{
value: "http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0010_heavy_rain_showers.png"
}
],
winddir16Point: "N",
winddirDegree: "10",
windspeedKmph: "11",
windspeedMiles: "7"
}
],
nearest_area: [
{
areaName: [
{
value: "New York"
}
],
country: [
{
value: "United States Of America"
}
],
latitude: "40.714",
longitude: "-74.006",
population: "8107916",
region: [
{
value: "New York"
}
],
weatherUrl: [
{
value: "http://free.worldweatheronline.com/New-York-weather/New-York/US.aspx"
}
]
}
],
request: [
{
query: "New York, United States Of America",
type: "City"
}
]
}
}
私はそれを解析するためにGSONを使用しているので、結果としてnull以外のオブジェクトが必要です。私の現在のクラスは次のとおりです。
気象情報:
public class MeteoInfo {
public MeteoInfo(){}
@SerializedName("current_condition")
private List<CurrentCondition> currentCondition;
@SerializedName("nearest_area")
private List<NearestArea> nearestArea;
public List<CurrentCondition> getCurrentCondition(){
return currentCondition;
}
public List<NearestArea> getNearestArea(){
return nearestArea;
}
}
現状:
public class CurrentCondition{
@SerializedName("weatherCode")
private int weatherCode;
@SerializedName("weatherDesc")
private List<Value> weatherDescs;
@SerializedName("temp_C")
private String temp_C;
@SerializedName("observation_time")
private String observation_time;
public int getWeatherCode() {
return weatherCode;
}
public void setWeatherCode(int weatherCode) {
this.weatherCode = weatherCode;
}
public List<Value> getweatherDescs() {
return weatherDescs;
}
public void setweatherDescs(List<Value> weatherText) {
this.weatherDescs = weatherText;
}
public String weatherDescsToString(){
String description= "";
if (weatherDescs!=null){
for (Value values:weatherDescs){
description= description + values.getValue();
}}
return description;
}
public String getTemp_C() {
return temp_C;
}
public void setTemp_C(String temp_C) {
this.temp_C = temp_C;
}
public String getObservation_time() {
return observation_time;
}
public void setObservation_time(String observation_time) {
this.observation_time = observation_time;
}
public class Value{
@SerializedName("value")
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
および最寄エリア:
public class NearestArea{
@SerializedName("areaName")
private List<Value> areaNames;
@SerializedName("country")
private List<Value> countries;
@SerializedName("latitude")
private String latitude;
@SerializedName("longitude")
private String longitude;
@SerializedName("region")
private List<Value> regions;
@SerializedName("weatherUrl")
private List<Value> urls;
public List<Value> getAreaNames() {
return areaNames;
}
public void setAreaNames(List<Value> areaNames) {
this.areaNames = areaNames;
}
public List<Value> getCountries() {
return countries;
}
public void setCountries(List<Value> countries) {
this.countries = countries;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public List<Value> getRegions() {
return regions;
}
public void setRegions(List<Value> regions) {
this.regions = regions;
}
public List<Value> getUrls() {
return urls;
}
public void setUrls(List<Value> urls) {
this.urls = urls;
}
public class Value{
@SerializedName("value")
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
今のままでいいと思いますが(改善の提案は非常に受け入れられています)、weatherDescの文字列やareaNamesの文字列など、下位レベルの文字列を取得する方法がわかりません。編集:クラスでjsonのすべての変数が必要ですか、それとも必要のない変数をスキップできますか?
EDIT2: MeteoInfo クラスを修正しました。json を取得して解析するコードは次のとおりです。
private class MeteoRetrieverAsyncTask extends AsyncTask<Void, Void, Void> {
private int weatherCode;
private String tempC;
private String observationTime;
private String weatherDesc;
private String latitude;
private String longitude;
private String areaName;
private String country;
private String region;
private String url;
private MeteoInfo meteoInfo;
@Override
protected Void doInBackground(Void... params) {
MeteoJsonParser msp = new MeteoJsonParser();
String url=apiBuilder();
try {
data= msp.getJSONData(url);
} catch (Exception e) {
e.printStackTrace();
}
if (data!=null){
try {
meteoInfo= msp.parseJson(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//Prendo i valori di CurrentCondition
for (CurrentCondition ccondition : meteoInfo.getCurrentCondition()) {
weatherCode= ccondition.getWeatherCode();
tempC= ccondition.getTemp_C();
observationTime = ccondition.getObservation_time();
for (CondValue wDesc: ccondition.getweatherDescs()){
weatherDesc= wDesc.getValue();
}
//Prendo i valori di NearestArea
for (NearestArea nArea: meteoInfo.getNearestArea()){
latitude = nArea.getLatitude();
longitude = nArea.getLongitude();
for (AreaValue aName: nArea.getAreaNames()){
areaName= aName.getValue();
}
for (AreaValue aCountry: nArea.getCountries()){
country = aCountry.getValue();
}
for (AreaValue aRegion: nArea.getRegions()){
region= aRegion.getValue();
}
for (AreaValue aUrl: nArea.getUrls()){
url= aUrl.getValue();
}
}
//Scrivo i valori sullo schermo
tv4.setText(tempC);
tv1.setText(weatherCode);
tv2.setText(weatherDesc);
tv3.setText(observationTime);
tv5.setText(latitude);
tv6.setText(longitude);
tv7.setText(areaName);
}
progressDialog.cancel();
}
}
private class CancelListener implements OnCancelListener {
AsyncTask<?, ?, ?> cancellableTask;
public CancelListener(AsyncTask<?, ?, ?> task) {
cancellableTask = task;
}
@Override
public void onCancel(DialogInterface dialog) {
cancellableTask.cancel(true);
}
}
MeteoJSONParser (前のコードで呼び出されます):
public class MeteoJsonParser {
public MeteoJsonParser() {
}
public InputStream getJSONData(String url) throws Exception {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,3000);
DefaultHttpClient httpClient = new DefaultHttpClient();
URI uri;
InputStream data = null;
try {
uri = new URI(url);
HttpGet method = new HttpGet(uri);
HttpResponse response = httpClient.execute(method);
data = response.getEntity().getContent();
} catch (Exception e) {
Log.e("TAG","Unable to download file: "+e);
throw e;
}
return data;
}
public MeteoInfo parseJson(InputStream inputStream) throws FileNotFoundException{
Gson gson = new Gson();
Reader r = new InputStreamReader(inputStream);
MeteoInfo dati = new MeteoInfo();
try {
dati = gson.fromJson(r, MeteoInfo.class);
} catch (Exception e) {
Log.e("JSON_Parser",e.toString());
}finally{
Log.d("JSON OK", "JSON Parsed");
}
return dati;
}
}
この行で NullPointerException を取得します。
for (CurrentCondition ccondition : meteoInfo.getCurrentCondition())