Hi I am new to Java and android and I'm trying to parse data from linked classes but I can not work out how to retrieve jsonObjects from some of the inner/nested JSONArrays?
I can retrieve objects from the outer JSONArray's but I can not see how to retrieve the nested JSONArray list objects from segments
inner JSONArrays within the StorlineData class.
When I try to parse data from the inner/nested JSONArrays the response looks like this:
Thanks in advance for your help.
JSON (I am unable to get data from trackPointsData and PlacesData)
[
{
"date": "20121212",
"summary": [
{
"activity": "walking",
"group": "walking",
"duration": 3333,
"distance": 3333,
"steps": 3333,
"calories": 300
},
],
"segments": [
{
"type": "place",
"startTime": "20121212T000000+0200",
"endTime": "20121212T071430+0200",
"place": {
"id": 1,
"type": "unknown",
"location": {
"lat": 55.55555,
"lon": 33.33333
}
},
"lastUpdate": "20130317T121143Z"
},
{
"type": "move",
"startTime": "20121212T071430+0200",
"endTime": "20121212T074617+0200",
"activities": [
{
"activity": "walking",
"group": "walking",
"manual": false,
"startTime": "20121212T071430+0200",
"endTime": "20121212T072732+0200",
"duration": 782,
"distance": 1251,
"steps": 1353,
"calories": 99,
"trackPoints": [
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T071430+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T072732+0200"
}
]
},
{
"activity": "transport",
"group": "transport",
"manual": false,
"startTime": "20121212T072732+0200",
"endTime": "20121212T074616+0200",
"duration": 1124,
"distance": 8443,
"trackPoints": [
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T072732+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T074208+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T074617+0200"
}
]
}
],
"lastUpdate": "20130317T121143Z"
},
{
"type": "place",
"startTime": "20121212T074617+0200",
"endTime": "20121212T100051+0200",
"place": {
"id": 2,
"type": "unknown",
"location": {
"lat": 55.55555,
"lon": 33.33333
}
},
"activities": [
{
"activity": "walking_on_treadmill",
"group": "walking",
"manual": true,
"duration": 270,
"steps": 303,
"calories": 30,
"trackPoints": []
}
],
"lastUpdate": "20130317T121143Z"
},
{
"type": "place",
"startTime": "20121212T100715+0200",
"endTime": "20121212T110530+0200",
"place": {
"id": 4,
"name": "test",
"type": "foursquare",
"foursquareId": "4df0fdb17d8ba370a011d24c",
"foursquareCategoryIds": ["4bf58dd8d48988d125941735"],
"location": {
"lat": 55.55555,
"lon": 33.33333
}
},
"activities": [
{
"activity": "walking",
"group": "walking",
"manual": false,
"startTime": "20121212T101215+0200",
"endTime": "20121212T101255+0200",
"duration": 40,
"distance": 18,
"steps": 37,
"calories": 99,
"trackPoints": [
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T101215+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T101255+0200"
}
]
}
],
"lastUpdate": "20130317T121143Z"
},
{
"type": "move",
"startTime": "20121212T110530+0200",
"endTime": "20121212T111129+0200",
"activities": [
{
"activity": "walking",
"group": "walking",
"manual": false,
"startTime": "20121212T110530+0200",
"endTime": "20121212T111128+0200",
"duration": 358,
"distance": 493,
"steps": 441,
"calories": 99,
"trackPoints": [
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T110531+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T110536+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T110947+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T111017+0200"
},
{
"lat": 55.55555,
"lon": 33.33333,
"time": "20121212T111129+0200"
}
]
}
],
"lastUpdate": "20130317T121143Z"
},
{
"type": "place",
"startTime": "20121212T111129+0200",
"endTime": "20121212T153638+0200",
"place": {
"id": 2,
"type": "unknown",
"location": {
"lat": 55.55555,
"lon": 33.33333
}
},
"activities": [
{
"activity": "zumba",
"manual": true,
"duration": 570,
"calories": 200,
"trackPoints": []
}
],
"lastUpdate": "20130317T121143Z"
},
{
"type": "place",
"startTime": "20121212T160744+0200",
"endTime": "20121212T232730+0200",
"place": {
"id": 1,
"type": "unknown",
"location": {
"lat": 55.55555,
"lon": 33.33333
}
},
"lastUpdate": "20130317T121143Z"
}
],
"caloriesIdle": 1785,
"lastUpdate": "20130317T121143Z"
}
]
Main Activity:
...
private MovesHandler<ArrayList<StorylineData>> storylineHandler = new MovesHandler<ArrayList<StorylineData>>() {
@Override
public void onSuccess(ArrayList<StorylineData> result) {
toggleProgress(false);
updateResponse(
...
+ "-----------Segment 1-------\t"
+ "StartTime:\t" + result.get(0).getSegments().get(0).getStartTime() + "\n"
+ " -Activities Array-\t" + "\n"
+ "- StartTime:\t" +
...
+ "-----------Segment 2-------\t" + "\n"
+ "- TrackPoints :\t" + result.get(0).getTrackPoints()+ "\n"//====Array Add
+ "- FoursquareId:\t" + result.get(0).getFoursquareId() + "\n"
+ "- ACt:\t" + result.get(0).getActivities()+ "\n"
+ "- Foursquare Id:\t" + result.get(0).getSegments().get(0).getPlace().getFoursquareId() + "\n"
+ "- Foursquare Id:\t" + result.get(0).getFoursquareId() + "\n"
+ "- Foursquare Category Ids:\t" + result.get(0).getSegments().get(0).getPlace().getFoursquareCategoryIds()+ "\n"
+ "- Activities:\t" + result.get(0).getSegments().get(0).getActivities()+ "\n"
);
}
...
StorylineData Class (I would like to retrieve jsonObjects from inner JSONArrays here in the storylineData class):
/**
* Parse a {@link org.json.JSONObject} from storyline {@link org.json.JSONArray}, then return the corresponding {@link StorylineData} object.
*
* @param jsonObject : the storyline JSON object received from server
* @return corresponding {@link StorylineData}
*/
public static StorylineData parse(JSONObject jsonObject) throws JSONException {
if (jsonObject != null) {
StorylineData storylineData = new StorylineData();
storylineData.date = jsonObject.optString("date");
storylineData.caloriesIdle = jsonObject.optInt("caloriesIdle");
storylineData.lastUpdate = jsonObject.optString("lastUpdate");
storylineData.summary = new ArrayList<>();
storylineData.segments = new ArrayList<>();
JSONArray summariesJsonArray = jsonObject.optJSONArray("summary");
if (summariesJsonArray != null)
for (int i = 0; i < summariesJsonArray.length(); i++) {
JSONObject summaryJsonObject = summariesJsonArray.optJSONObject(i);
if (summaryJsonObject != null) {
summariesJsonArray.getJSONObject(i).getString("distance");
String group = summaryJsonObject.optString("group");
Integer distance = summaryJsonObject.optInt("distance");
storylineData.setDistance(distance);
...
storylineData.summary.add(SummaryData.parse(summaryJsonObject));
Log.d("StorylineDataCls \t sJo", summaryJsonObject.toString() + "Log\n");
System.out.println("print distance" + summariesJsonArray.getJSONObject(i).getString("distance"));
System.out.println("print summary" + summaryJsonObject);
}
}
JSONArray segmentsJsonArray = jsonObject.optJSONArray("segments");
if (segmentsJsonArray != null) {
for (int i = 0; i < segmentsJsonArray.length(); i++) {
JSONObject segment = segmentsJsonArray.optJSONObject(i);
if (segment != null) {
JSONArray activitiesJsonArray = segment.optJSONArray("activities");
if (activitiesJsonArray!=null) {
for (int j = 0; j < activitiesJsonArray.length(); j++) {
JSONObject trackPoints = activitiesJsonArray.optJSONObject(j);
if(trackPoints != null){
...
storylineData.trackPoints.add(TrackPointsData.parse(trackPoints));
}
}
}
..
Log.d("StorylineDataCls \t sSo", segment.toString());
System.out.println("print segment" + segment);
//System.out.println("print segments" + segments);
System.out.println("print segmentsJsonArray" + segmentsJsonArray);
}
}
}
return storylineData;
}
return null;
}
============PARSER METHODS IN LINKED CLASSES================
PlaceData Class:
/**
* Parse a {@link org.json.JSONObject} of place, then return the corresponding {@link PlaceData} object.
* @param jsonObject : the 'place' JSON object to parse
* @return corresponding {@link PlaceData}
*/
public static PlaceData parse(JSONObject jsonObject) {
if (jsonObject != null) {
PlaceData placeData = new PlaceData();
placeData.id = jsonObject.optString("id");
placeData.name = jsonObject.optString("name");
placeData.type = jsonObject.optString("type");
placeData.foursquareId = jsonObject.optString("foursquareId");
JSONObject location = jsonObject.optJSONObject("location");
if (location != null) {
placeData.location = LocationData.parse(location);
}
JSONArray trackPointsJSONArray = jsonObject.optJSONArray("foursquareCategoryIds");
placeData.foursquareCategoryIds = new ArrayList<String>();
if (trackPointsJSONArray != null) {
for (int i = 0; i < trackPointsJSONArray.length(); i++) {
String categoryId = trackPointsJSONArray.optString(i);
if (categoryId != null && categoryId.length() > 0) {
placeData.foursquareCategoryIds.add(categoryId);
}
}
}
return placeData;
}
return null;
}
}
LocationData Class:
/**
* Parse a {@link org.json.JSONObject} from trackPoints {@link org.json.JSONArray}, then return the corresponding
* {@link LocationData} object.
* @param jsonObject : the 'trackPoint' JSON object to parse
* @return corresponding {@link LocationData}
*/
public static LocationData parse(JSONObject jsonObject) {
if (jsonObject != null) {
LocationData trackPointsData = new LocationData();
trackPointsData.lat = jsonObject.optString("lat");
trackPointsData.lon = jsonObject.optString("lon");
return trackPointsData;
}
return null;
}
}
TrackPointData Class:
/**
* Parse a {@link org.json.JSONObject} from trackPoints {@link org.json.JSONArray}, then return the corresponding
* {@link TrackPointsData} object.
* @param jsonObject : the 'trackPoint' JSON object to parse
* @return corresponding {@link TrackPointsData}
*/
public static TrackPointsData parse(JSONObject jsonObject) {
if (jsonObject != null) {
TrackPointsData trackPointsData = new TrackPointsData();
trackPointsData.lat = jsonObject.optString("lat");
trackPointsData.lon = jsonObject.optString("lon");
trackPointsData.time = jsonObject.optString("time");
return trackPointsData;
}
return null;
}
}
ActivityData Class:
/**
* Parse a {@link org.json.JSONObject} from activities {@link org.json.JSONArray}, then return the corresponding
* {@link ActivityData} object.
* @param jsonObject : the 'activity' JSON object to parse
* @return corresponding {@link ActivityData}
*/
public static ActivityData parse(JSONObject jsonObject) {
if (jsonObject != null) {
ActivityData activityData = new ActivityData();
activityData.activity = jsonObject.optString("activity");
activityData.group = jsonObject.optString("group");
activityData.manual = jsonObject.optString("manual");
activityData.startTime = jsonObject.optString("startTime");
activityData.endTime = jsonObject.optString("endTime");
activityData.duration = jsonObject.optInt("duration");
activityData.distance = jsonObject.optInt("distance");
activityData.steps = jsonObject.optInt("steps");
activityData.calories = jsonObject.optInt("calories");
JSONArray trackPointsJSONArray = jsonObject.optJSONArray("trackPoints");
activityData.trackPoints = new ArrayList<TrackPointsData>();
if (trackPointsJSONArray != null) {
for (int i = 0; i < trackPointsJSONArray.length(); i++) {
JSONObject summaryJsonObject = trackPointsJSONArray.optJSONObject(i);
if (summaryJsonObject != null) {
activityData.trackPoints.add(TrackPointsData.parse(summaryJsonObject));
}
}
}
return activityData;
}
return null;
}
}
SegmentData Class:
/**
* Parse a {@link org.json.JSONObject} from segments {@link org.json.JSONArray}, then return the corresponding {@link SegmentData} object.
* @param jsonObject : the 'segment' JSON object to parse
* @return corresponding {@link SegmentData}
*/
public static SegmentData parse(JSONObject jsonObject) {
if (jsonObject != null) {
SegmentData segmentData = new SegmentData();
segmentData.type = jsonObject.optString("type");
segmentData.startTime = jsonObject.optString("startTime");
segmentData.endTime = jsonObject.optString("endTime");
segmentData.lastUpdate = jsonObject.optString("lastUpdate");
segmentData.name = jsonObject.optString("name");
JSONArray activitiesJSONArray = jsonObject.optJSONArray("activities");
segmentData.activities = new ArrayList<ActivityData>();
if (activitiesJSONArray != null) {
for (int i = 0; i < activitiesJSONArray.length(); i++) {
JSONObject activityJsonObject = activitiesJSONArray.optJSONObject(i);
if (activityJsonObject != null) {
placeData = (PlaceData) activityJsonObject.opt(String.valueOf(placeData));
segmentData.setPlace(placeData);
segmentData.activities.add(ActivityData.parse(activityJsonObject));
}
}
}
JSONObject placeJsonObject = jsonObject.optJSONObject("place");
if (placeJsonObject != null) {
segmentData.place = PlaceData.parse(placeJsonObject);
}
return segmentData;
}
return null;
}
}
SummaryData Class:
/**
* Parse a {@link org.json.JSONObject} from summary {@link org.json.JSONArray}, then return the corresponding {@link SummaryData} object.
* @param jsonObject : the 'summary' JSON object to parse
* @return corresponding {@link SummaryData}
*/
public static SummaryData parse(JSONObject jsonObject) {
if (jsonObject != null) {
SummaryData summary = new SummaryData();
summary.activity = jsonObject.optString("activity");
summary.group = jsonObject.optString("group");
summary.duration = jsonObject.optInt("duration");
summary.distance = jsonObject.optInt("distance");
summary.steps = jsonObject.optInt("steps");
summary.calories = jsonObject.optInt("calories");
//Log.d("json", summary.toString());
return summary;
}
return null;
}
}
HTTPCall Class: ...
public static void getDailyStorylineList(final MovesHandler<ArrayList<StorylineData>> handler,
final String specificSummary,
final String from,
final String to,
final String pastDays,
final String updatedSince,
final boolean needTrackPoints) {
new Thread(new Runnable() {
@Override
public void run() {
try {
/* Refresh access token if only AuthData.MOVES_REFRESHBEFORE days are there to expire current token */
AuthData.refreshAccessTokenIfNeeded();
/* Exchange the authorization code we obtained after login to get access token */
HashMap<String, String> nameValuePairs = new HashMap<String, String>();
nameValuePairs.put("access_token", AuthData.getAuthData().getAccessToken());
// if (specificSummary != null && specificSummary.length() > 0) nameValuePairs.put("specificSummary", specificSummary);//att
if (from != null && from.length() > 0) nameValuePairs.put("from", from);
if (to != null && to.length() > 0) nameValuePairs.put("to", to);
if (pastDays != null && pastDays.length() > 0) nameValuePairs.put("pastDays", pastDays);
if (updatedSince != null && updatedSince.length() > 0) nameValuePairs.put("updatedSince", updatedSince);
if (needTrackPoints) nameValuePairs.put("trackPoints", "true");
URL url = new URL(MovesAPI.API_BASE + MovesAPI.API_PATH_STORYLINE + (specificSummary != null ? specificSummary : "") + "?" + Utilities.encodeUrl(nameValuePairs));
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.connect();
if (urlConnection.getResponseCode() != 200) {
/* All other HTTP errors from Moves will fall here */
handler.onFailure(getErrorStatus(Utilities.readStream(urlConnection.getErrorStream()), urlConnection.getResponseCode()), "Server not responded with success ("+ urlConnection.getResponseCode() +")");
return;
}
String response = Utilities.readStream(urlConnection.getInputStream());
Object object = new JSONTokener(response).nextValue();
if (object instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) object;
ArrayList<StorylineData> storylineData = new ArrayList<StorylineData>();
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject storylineJsonObject = jsonArray.optJSONObject(i);
if (storylineJsonObject != null) {
storylineData.add(StorylineData.parse(storylineJsonObject));
}
}
}
handler.onSuccess(storylineData);
} else {
handler.onFailure(MovesStatus.INVALID_RESPONSE, "Expected a JSONArray from server, but failed");
}
} catch (Exception ex) {
ex.printStackTrace();
handler.onFailure(MovesStatus.UNEXPECTED_ERROR, "An unexpected error occured, please check logcat");
}
}
}).start();
}
MovesHandler Class
/**
* This interface will act as a handler who notifies all success and failures
*
*
* @param <T> : A generic class, which probably will be the response type after success
* @see MovesStatus
*/
public interface MovesHandler<T> {//T stands for generic type
/**
* Implement this method to get success notifications along with the result
* @param result : Result of the operation completed with this handler
*/
public void onSuccess(T result);
/**
* Implement this method to get failure notifications along with the {@link MovesStatus} code and a brief message
* @param status : Status code of the failure
* @param message : A brief message about the reason behind failure
*/
public void onFailure(MovesStatus status, String message);
}
MovesAPI Class
/**
* Get daily storylines for user.
* @see <a href="https://dev.moves-app.com/docs/api_storyline">Moves Developer Page for Daily Storyline</a>
* @see SummaryListData
* @param handler : An implemented {@link MovesHandler} with an {@link ArrayList} of {@link StorylineData}.
* This handler will get notified when the request completes.
* @param date : date in yyyyMMdd or yyyy-MM-dd format
* @param updatedSince : [optional] if set, return only days which data has been updated since
* given time stamp in ISO 8601 (yyyyMMdd’T’HHmmssZ) format, pass <code>null</code> if not required.
* @param needTrackPoints : if true, the returned activities also include {@link TrackPointsData} information.
* Including track points limits the query range to 7 days.
*/
public static void getStoryline_SingleDay(MovesHandler<ArrayList<StorylineData>> handler, String date, String updatedSince, boolean needTrackPoints) {
if (AuthData.isAuthenticated()) {
HTTPCall.getDailyStorylineList(handler, "/" + date, null, null, null, updatedSince, needTrackPoints);
} else {
handler.onFailure(MovesStatus.NOT_AUTHENTICATED, "You are not yet authenticated with required scopes!");
}
}
SummaryListData Class:
public static SummaryListData parse(JSONObject jsonObject) {
if (jsonObject != null) {
SummaryListData summary = new SummaryListData();
summary.date = jsonObject.optString("date");
summary.caloriesIdle = jsonObject.optString("caloriesIdle");
summary.lastUpdate = jsonObject.optString("lastUpdate");
summary.summaries = new ArrayList<SummaryData>();
JSONArray summariesJsonArray= jsonObject.optJSONArray("summary");
if (summariesJsonArray != null) {
for (int i = 0; i < summariesJsonArray.length(); i++) {
JSONObject summaryJsonObject = summariesJsonArray.optJSONObject(i);
if (summaryJsonObject != null) {
summary.summaries.add(SummaryData.parse(summaryJsonObject));
Log.d("summaryHandler", summaryJsonObject.toString());
}
}
}
return summary;
}
return null;
}
}