Reputation: 35
Not sure where I make a mistake.
Code:
public class VaccinationTotalUSA extends Fragment {
RecyclerView rvRecentRecord;
ProgressBar progressBar;
private static final String TAG = VaccinationTotalUSA.class.getSimpleName();
ArrayList<VaccinationTimeline> recentRecords;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_vaccination, container, false);
// call view
rvRecentRecord = view.findViewById(R.id.vaccinationRecord);
progressBar = view.findViewById(R.id.progress_circular_vaccination);
rvRecentRecord.setLayoutManager(new LinearLayoutManager(getActivity()));
// Volley Fetch
getDataFromServer();
return view;
}
private void showRecyclerView() {
VaccinationAdapter vaccinationAdapter = new VaccinationAdapter(recentRecords);
rvRecentRecord.setAdapter(vaccinationAdapter);
}
private void getDataFromServer() {
String url = "https://disease.sh/v3/covid-19/vaccine/coverage/countries/USA";
recentRecords = new ArrayList<>();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressBar.setVisibility(View.GONE);
if (response != null) {
Log.e(TAG, "onResponse:" + response);
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("timeline");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject data = jsonArray.getJSONObject(i);
Iterator key = data.keys();
while (key.hasNext()) {
String timedata = key.next().toString();
recentRecords.add(new VaccinationTimeline(key, timedata));
}
}
showRecyclerView();
}catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
Log.e(TAG, "onResponse" + error);
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
}
JSON: Note: Can't really use jsonObject.getString() on timeline nested list since everything gets updated each day, i.e, 4/18/2021 data comes in, 3/19/2021 will be removed
{
"country": "USA",
"timeline": {
"3/19/21": 118313818,
"3/20/21": 121441497,
"3/21/21": 124481412,
"3/22/21": 126509736,
"3/23/21": 128217029,
"3/24/21": 130473853,
"3/25/21": 133305295,
"3/26/21": 136684688,
"3/27/21": 140180735,
"3/28/21": 143462691,
"3/29/21": 145812835,
"3/30/21": 147602345,
"3/31/21": 150273292,
"4/1/21": 153631404,
"4/2/21": 157606463,
"4/3/21": 161688422,
"4/4/21": 165053746,
"4/5/21": 167187795,
"4/6/21": 168592075,
"4/7/21": 171476655,
"4/8/21": 174879716,
"4/9/21": 178837781,
"4/10/21": 183467709,
"4/11/21": 187047131,
"4/12/21": 189692045,
"4/13/21": 192282781,
"4/14/21": 194791836,
"4/15/21": 198317040,
"4/16/21": 202282923,
"4/17/21": 202282923
}
}
I have tried many ways to display this json data, with and without iterator. I want to use iterator because I want to be able to retrieve both list name and data inside of list, i.e, 4/17/2021:1111111 Error Output:
E/VaccinationTotalUSA: onResponse:{"country":"USA","timeline":{"3/19/21":118313818,"3/20/21":121441497,"3/21/21":124481412,"3/22/21":126509736,"3/23/21":128217029,"3/24/21":130473853,"3/25/21":133305295,"3/26/21":136684688,"3/27/21":140180735,"3/28/21":143462691,"3/29/21":145812835,"3/30/21":147602345,"3/31/21":150273292,"4/1/21":153631404,"4/2/21":157606463,"4/3/21":161688422,"4/4/21":165053746,"4/5/21":167187795,"4/6/21":168592075,"4/7/21":171476655,"4/8/21":174879716,"4/9/21":178837781,"4/10/21":183467709,"4/11/21":187047131,"4/12/21":189692045,"4/13/21":192282781,"4/14/21":194791836,"4/15/21":198317040,"4/16/21":202282923,"4/17/21":202282923}}
W/System.err: org.json.JSONException: Value {"country":"USA","timeline":{"3\/19\/21":118313818,"3\/20\/21":121441497,"3\/21\/21":124481412,"3\/22\/21":126509736,"3\/23\/21":128217029,"3\/24\/21":130473853,"3\/25\/21":133305295,"3\/26\/21":136684688,"3\/27\/21":140180735,"3\/28\/21":143462691,"3\/29\/21":145812835,"3\/30\/21":147602345,"3\/31\/21":150273292,"4\/1\/21":153631404,"4\/2\/21":157606463,"4\/3\/21":161688422,"4\/4\/21":165053746,"4\/5\/21":167187795,"4\/6\/21":168592075,"4\/7\/21":171476655,"4\/8\/21":174879716,"4\/9\/21":178837781,"4\/10\/21":183467709,"4\/11\/21":187047131,"4\/12\/21":189692045,"4\/13\/21":192282781,"4\/14\/21":194791836,"4\/15\/21":198317040,"4\/16\/21":202282923,"4\/17\/21":202282923}} of type org.json.JSONObject cannot be converted to JSONArray
at org.json.JSON.typeMismatch(JSON.java:112)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.programming_concept.senior_project.VaccinationTotalUSA$1.onResponse(VaccinationTotalUSA.java:83)
W/System.err: at com.programming_concept.senior_project.VaccinationTotalUSA$1.onResponse(VaccinationTotalUSA.java:69)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Upvotes: 1
Views: 2306
Reputation: 1924
You're trying to set the "timeline" value to a JSONArray
variable while that value would actually be a JSONObject
. Here's a way you can retrieve both the key and value:
JSONObject jsonObject = new JSONObject(response);
JSONObject subObject = jsonObject.getJSONObject("timeline");
// Separate the keys into a JSONArray
JSONArray keys = subObject.names();
// Retrieve the keys and values
for(int i=0; i < keys.length(); i++) {
String key = keys.getString(i);
int value = subObject.getInt(key);
Log.d("LOG_TAG", key + " : " + value);
}
Upvotes: 0
Reputation: 347
You can try the follwing code. I have hardcoded the json response in the Main class itself. Also I have used ObjectMapper which is much better than using JsonObject class
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class AssessmentBridgeApplication {
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
String json = "{\"country\":\"USA\",\"timeline\":{\"3/19/21\":118313818,\"3/20/21\":121441497,\"3/21/21\":124481412,\"3/22/21\":126509736,\"3/23/21\":128217029,\"3/24/21\":130473853,\"3/25/21\":133305295,\"3/26/21\":136684688,\"3/27/21\":140180735,\"3/28/21\":143462691,\"3/29/21\":145812835,\"3/30/21\":147602345,\"3/31/21\":150273292,\"4/1/21\":153631404,\"4/2/21\":157606463,\"4/3/21\":161688422,\"4/4/21\":165053746,\"4/5/21\":167187795,\"4/6/21\":168592075,\"4/7/21\":171476655,\"4/8/21\":174879716,\"4/9/21\":178837781,\"4/10/21\":183467709,\"4/11/21\":187047131,\"4/12/21\":189692045,\"4/13/21\":192282781,\"4/14/21\":194791836,\"4/15/21\":198317040,\"4/16/21\":202282923,\"4/17/21\":202282923}}";
ObjectMapper mapper = new ObjectMapper();
VaccinationRecords vaccinationRecords = new VaccinationRecords();
vaccinationRecords = mapper.readValue(json, VaccinationRecords.class);
System.out.println(vaccinationRecords.getTimeline());
}
}
=========================
import java.util.Map;
public class VaccinationRecords {
private String country;
Map<String, Object> timeline;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Map<String, Object> getTimeline() {
return timeline;
}
public void setTimeline(Map<String, Object> timeline) {
this.timeline = timeline;
}
}
Upvotes: 0
Reputation: 1006614
There is no array in that JSON. In JSON, an array is denoted by square brackets ([
and ]
). There are no square brackets in that JSON.
You have an outer JSON object, with two properties: country
and timeline
. timeline
is another JSON object, with keys based on dates and values that are integers.
So, you need to revise your plans to work with the JSON as it is, which means JSONArray jsonArray = jsonObject.getJSONArray("timeline");
needs to turn into JSONObject timelineJson = jsonObject.getJSONObject("timeline");
.
And note that there are many better JSON parsers available for Android, such as Moshi.
Upvotes: 1