Мое приложение анализирует данные JSON из API Google Civic Information.Иногда данные могут быть недоступны для конкретного JSONobject или массива.В моем случае я пытаюсь проанализировать 8 полей из 2 JSONObjects ("офисы", "должностные лица") и 1 массива JSON ("адрес").Не все официальные лица будут иметь данные фотографии, адресные данные. Полный ответ JSON:
{
"normalizedInput": {
"line1": "2613 Irvington Avenue",
"city": "San Bernardino",
"state": "CA",
"zip": "92407"
},
"offices": [
{
"name": "President of the United States",
"levels": [
"country"
],
"roles": [
"headOfState",
"headOfGovernment"
]
},
{
"name": "Vice-President of the United States",
"levels": [
"country"
],
"roles": [
"deputyHeadOfGovernment"
]
},
{
"name": "United States Senate",
"levels": [
"country"
],
"roles": [
"legislatorUpperBody"
]
},
{
"name": "United States House of Representatives CA-31",
"levels": [
"country"
],
"roles": [
"legislatorLowerBody"
]
},
{
"name": "Governor",
"levels": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
]
},
{
"name": "Lieutenant Governor",
"levels": [
"administrativeArea1"
],
"roles": [
"deputyHeadOfGovernment"
]
},
{
"name": "CA State Senate District 23",
"levels": [
"administrativeArea1"
],
"roles": [
"legislatorUpperBody"
]
},
{
"name": "CA State Assembly District 40",
"levels": [
"administrativeArea1"
],
"roles": [
"legislatorLowerBody"
]
},
{
"name": "City Treasurer"
},
{
"name": "Mayor"
},
{
"name": "City Attorney"
},
{
"name": "City Clerk"
},
{
"name": "Sheriff-Coroner"
},
{
"name": "Auditor-Controller-Treasurer-Tax Collector"
},
{
"name": "District Attorney"
},
{
"name": "Assessor-Clerk-Recorder"
},
{
"name": "San Bernardino County Superior Court Judge"
},
{
"name": "Board of Supervisors, District 5"
},
{
"name": "Board of Equalization Member District 1"
},
{
"name": "Secretary of State"
},
{
"name": "State Treasurer"
},
{
"name": "Attorney General"
},
{
"name": "State Superintendent of Public Instruction"
},
{
"name": "State Controller"
},
{
"name": "Board of Equalization Member District 2"
},
{
"name": "Board of Equalization Member District 4"
},
{
"name": "Board of Equalization Member District 3"
},
{
"name": "Insurance Commissioner"
}
],
"officials": [
{
"name": "Donald J. Trump",
"address": [
{
"line1": "The White House",
"line2": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"zip": "20500"
}
],
"party": "Republican",
"phones": [
"(202) 456-1111"
],
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+whitehouse"
},
{
"type": "Facebook",
"id": "whitehouse"
},
{
"type": "Twitter",
"id": "potus"
},
{
"type": "YouTube",
"id": "whitehouse"
}
]
},
{
"name": "Mike Pence",
"address": [
{
"line1": "The White House",
"line2": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"zip": "20500"
}
],
"party": "Republican",
"phones": [
"(202) 456-1111"
],
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+whitehouse"
},
{
"type": "Facebook",
"id": "whitehouse"
},
{
"type": "Twitter",
"id": "VP"
}
]
},
{
"name": "Kamala D. Harris",
"address": [
{
"line1": "112 Hart Senate Office Building",
"city": "Washington",
"state": "DC",
"zip": "20510"
}
],
"party": "Democratic",
"phones": [
"(202) 224-3553"
],
"channels": [
{
"type": "Twitter",
"id": "KamalaHarris"
},
{
"type": "YouTube",
"id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
}
]
},
{
"name": "Dianne Feinstein",
"address": [
{
"line1": "331 Hart Senate Office Building",
"city": "Washington",
"state": "DC",
"zip": "20510"
}
],
"party": "Democratic",
"phones": [
"(202) 224-3841"
],
"photoUrl": "http://bioguide.congress.gov/bioguide/photo/F/F000062.jpg",
"channels": [
{
"type": "Facebook",
"id": "SenatorFeinstein"
},
{
"type": "Twitter",
"id": "SenFeinstein"
},
{
"type": "YouTube",
"id": "SenatorFeinstein"
}
]
},
{
"name": "Pete Aguilar",
"address": [
{
"line1": "109 Cannon House Office Building",
"city": "Washington",
"state": "DC",
"zip": "20515"
}
],
"party": "Democratic",
"phones": [
"(202) 225-3201"
],
"photoUrl": "https://aguilar.house.gov/sites/aguilar.house.gov/files/styles/congress_image_medium/public/wysiwyg_uploaded/Headshot_0.jpg?itok=LSt7qkOV",
"channels": [
{
"type": "Facebook",
"id": "reppeteaguilar"
},
{
"type": "Twitter",
"id": "RepPeteAguilar"
},
{
"type": "YouTube",
"id": "UCIXCmfuRWrbgdTw257_lxJQ"
},
{
"type": "YouTube",
"id": "UCxwbFLOlKDsXrwizV5jah7g"
}
]
},
{
"name": "Gavin Newsom",
"address": [
{
"line1": "c/o State Capitol",
"line2": "Suite 1173",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-2841"
],
"channels": [
{
"type": "Twitter",
"id": "GavinNewsom"
}
]
},
{
"name": "Eleni Kounalakis",
"address": [
{
"line1": "State Capitol",
"line2": "Suite 1114",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-8994"
]
},
{
"name": "Mike Morrell",
"address": [
{
"line1": "STATE CAPITOL",
"line2": "1303 10TH ST RM 3056",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Republican",
"phones": [
"(909) 919-7731"
],
"photoUrl": "http://senate.ca.gov/sites/senate.ca.gov/files/senator_photos/morrell-mike.jpg",
"emails": [
"Senator.Morrell@senate.ca.gov"
],
"channels": [
{
"type": "Twitter",
"id": "MikeMorrellGOP"
},
{
"type": "Facebook",
"id": "MikeMorrellGOP"
}
]
},
{
"name": "James C. Ramos",
"address": [
{
"line1": "PO BOX 942849",
"city": "Sacramento",
"state": "CA",
"zip": "94249"
}
],
"party": "Democratic Party",
"phones": [
"(909) 476-5023"
],
"emails": [
"assemblymember.ramos@assembly.ca.gov"
]
},
{
"name": "David C. Kennedy",
"address": [
{
"line1": "300 N. \"D\" Street",
"line2": "2nd Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5022"
]
},
{
"name": "R. Carey Davis",
"address": [
{
"line1": "300 N. \"D\" Street - 6th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5133"
],
"channels": [
{
"type": "Facebook",
"id": "MayorCareyDavis"
}
]
},
{
"name": "Gary D. Saenz",
"address": [
{
"line1": "300 N. \"D\" Street",
"line2": "6th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5355"
],
"emails": [
"Attorney@sbcity.org"
]
},
{
"name": "Georgeann \"Gigi\" Hanna",
"address": [
{
"line1": "300 N. \"D\" Street",
"line2": "2nd Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92418"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 384-5002"
]
},
{
"name": "John McMahon",
"address": [
{
"line1": "655 East Third Street",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(760) 956-5001"
],
"emails": [
"paffairs@sbcsd.org"
],
"channels": [
{
"type": "Facebook",
"id": "sbcountysheriff"
},
{
"type": "Twitter",
"id": "sbcountysheriff"
}
]
},
{
"name": "Oscar Valdez",
"address": [
{
"line1": "222 W. Hospitality Lane",
"line2": "4th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 382-7014"
]
},
{
"name": "Michael Ramos",
"address": [
{
"line1": "303 West 3rd Street",
"line2": "6th Floor",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 382-3669"
],
"channels": [
{
"type": "Facebook",
"id": "SanBernardinoCountyDistrictAttorney"
},
{
"type": "Twitter",
"id": "sbcountyda"
}
]
},
{
"name": "Bob Dutton",
"address": [
{
"line1": "First Floor",
"line2": "222 W. Hospitality Lane",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(855) 732-2575"
]
},
{
"name": "Denise Trager Dvorak",
"party": "Nonpartisan"
},
{
"name": "Josie Gonzales",
"address": [
{
"line1": "385 N. Arrowhead Ave.",
"line2": "5th Fl.",
"city": "San Bernardino",
"state": "CA",
"zip": "92415"
}
],
"party": "Nonpartisan",
"phones": [
"(909) 387-4565"
],
"channels": [
{
"type": "Facebook",
"id": "supervisorgonzales"
},
{
"type": "Twitter",
"id": "SupervisorJosie"
}
]
},
{
"name": "Ted Gaines"
},
{
"name": "Alex Padilla",
"address": [
{
"line1": "1500 11th Street,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 653-6814"
]
},
{
"name": "Fiona Ma",
"address": [
{
"line1": "P.O. Box 942809",
"city": "Sacramento",
"state": "CA",
"zip": "94209"
}
],
"party": "Democratic",
"phones": [
"(916) 653-2995"
]
},
{
"name": "Xavier Becerra",
"address": [
{
"line1": "Office of the Attorney General",
"line2": "1300 \"I\" Street",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-9555"
],
"channels": [
{
"type": "Facebook",
"id": "XavierBecerra"
},
{
"type": "Twitter",
"id": "AGBecerra"
}
]
},
{
"name": "Tony K. Thurmond",
"address": [
{
"line1": "1430 N Street,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Nonpartisan",
"phones": [
"(916) 319-0800"
]
},
{
"name": "Betty T. Yee",
"address": [
{
"line1": "300 Capitol Mall,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic",
"phones": [
"(916) 445-2636"
],
"channels": [
{
"type": "Facebook",
"id": "137732083043662"
},
{
"type": "Twitter",
"id": "CAController"
}
]
},
{
"name": "Malia Cohen"
},
{
"name": "Mike Schaefer"
},
{
"name": "Antonio Vazquez"
},
{
"name": "Ricardo Lara",
"address": [
{
"line1": "300 Capitol Mall,",
"city": "Sacramento",
"state": "CA",
"zip": "95814"
}
],
"party": "Democratic"
}
]
}
Поскольку данные обновляются Google, у меня нет возможности узнать, какие поля будут заполнены.Значит ли это, что я должен создавать условия и конструкторы для каждого случая?Я пытался использовать функцию optString, чтобы установить строку по умолчанию для пустых значений, но я не думаю, что я использую их правильно.
Вот мой класс Rep, который определяет объект:
package com.example.gabe.politicianspulse;
import android.widget.ImageView;
public class Reps {
private String officeName;
private String officialName;
private String party;
private String photoUrl;
private String line1;
private String city;
private String state;
private String zip;
private String phones;
//continue to develop this with other values such as phone, photo, address etc.
public Reps(){
}
public Reps(String officeName, String officialName, String party, String photoUrl, String line1, String city, String state, String zip, String phones) {
this.officeName = officeName;
this.officialName = officialName;
this.party = party;
this.photoUrl = photoUrl;
this.line1 = line1;
this.city = city;
this.state = state;
this.zip = zip;
this.phones = phones;
}
public Reps(String officeName, String officialName, String party, String line1, String city, String state, String zip, String phones) {
this.officeName = officeName;
this.officialName = officialName;
this.party = party;
this.line1 = line1;
this.city = city;
this.state = state;
this.zip = zip;
this.phones = phones;
}
public Reps(String officeName, String officialName, String party, String photoUrl) {
this.officeName = officeName;
this.officialName = officialName;
this.party = party;
this.photoUrl = photoUrl;
}
public Reps(String officeName, String officialName, String party) {
this.officeName = officeName;
this.officialName = officialName;
this.party = party;
}
public Reps(String officeName) {
this.officeName = officeName;
}
public Reps(String name, String party) {
this.officialName = name;
this.party = party;
}
public Reps(String officeName, String officialName, String party, String line1, String city, String state, String zip) {
this.officeName = officeName;
this.officialName = officialName;
this.party = party;
this.line1 = line1;
this.city = city;
this.state = state;
this.zip = zip;
}
public String getOfficeName() {
return officeName;
}
public void setOfficeName(String officeName) {
this.officeName = officeName;
}
public String getOfficialName() {
return officialName;
}
public void setOfficialName(String officialName) {
this.officialName = officialName;
}
public String getParty() {
return party;
}
public void setParty(String party) {
this.party = party;
}
public String getPhotoUrl() {
return photoUrl;
}
public void setPhotoUrl(String photoUrl) {
this.photoUrl = photoUrl;
}
public String getLine1() {
return line1;
}
public void setLine1(String line1) {
this.line1 = line1;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getPhones() {
return phones;
}
public void setPhones(String phones) {
this.phones = phones;
}
}
Вот моя функция разбора.У меня есть 2 разных реализации, которые я пробовал.Сначала я попытался использовать функцию optString для размещения пустых значений, например, так:
private void getData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressDialog.dismiss();
try{
JSONObject jsonObject = new JSONObject(response);
//first loop through offices array. Retrieve officeName value
JSONArray officesArray = jsonObject.getJSONArray("offices"); //One array for offices
JSONArray officialsArray = jsonObject.getJSONArray("officials"); //one array for officials
for (int i = 0; i < officesArray.length(); i++) {
JSONObject jsonOffices = officesArray.getJSONObject(i);
JSONObject jsonOfficials = officialsArray.getJSONObject(i);
JSONArray jsonAddress = jsonOfficials.getJSONArray("address"); //Declare address array here?
Reps reps1 = new Reps(jsonOffices.optString("name", "No Data"),
jsonOfficials.optString("name", "No Data"),
jsonOfficials.optString("party", "No data"),
jsonOfficials.optString("photoUrl", "No data"),
jsonAddress.getJSONObject(0).optString("line1", "No data"),
jsonAddress.getJSONObject(0).optString("city", "No data"),
jsonAddress.getJSONObject(0).optString("state", "No data"),
jsonAddress.getJSONObject(0).optString("zip", "No data")
);
repList.add(reps1);
/*if(jsonOfficials.has("photoUrl")){
Reps reps = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"),
jsonOfficials.getString("photoUrl"));
repList.add(reps);
}else{
Reps ree = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"));
repList.add(ree);
}
//object with photoURL data, but no address data
*/ }
adapter = new RepRvAdapter(repList, getApplicationContext());
myrv.setAdapter(adapter);
}catch (JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
Затем я попытался использовать различные условные выражения для создания объектов для каждого случая, например, так: (Я добавил условие только для объектов без данных photoUrl длясейчас. Я хотел бы знать, если это лучший подход, прежде чем я напишу остальные условия.)
//fetch json data from Civic API
private void getData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressDialog.dismiss();
try{
JSONObject jsonObject = new JSONObject(response);
//first loop through offices array. Retrieve officeName value
JSONArray officesArray = jsonObject.getJSONArray("offices"); //One array for offices
JSONArray officialsArray = jsonObject.getJSONArray("officials"); //one array for officials
for (int i = 0; i < officesArray.length(); i++) {
JSONObject jsonOffices = officesArray.getJSONObject(i);
JSONObject jsonOfficials = officialsArray.getJSONObject(i);
//JSONArray jsonAddress = jsonOfficials.getJSONArray("address"); //Declare address array here?
if(jsonOfficials.has("photoUrl")){
Reps reps = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"),
jsonOfficials.getString("photoUrl"));
repList.add(reps);
}else{
Reps ree = new Reps(jsonOffices.getString("name"),
jsonOfficials.getString("name"),
jsonOfficials.getString("party"));
repList.add(ree);
}
//object with photoURL data, but no address data
}
adapter = new RepRvAdapter(repList, getApplicationContext());
myrv.setAdapter(adapter);
}catch (JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
Я бы предпочел использовать метод, аналогичный функции optstring, вместо создания условия длякаждый случай, поскольку это было бы утомительно и занимало много времени.Я думаю, мой вопрос к вам, как бы вы подошли к этой проблеме наиболее эффективным способом?