Destry Destry - 5 months ago 20
Android Question

Unable to return JSON Object, within Object in Android app

So I have an Android app I am working on that makes an API call to the server and returns JSON information. Now in my android app I can parse the JSON but only up until the first array. After that it says that category doesn't exist.

Here is the JSON response layout:

[
{
"success": 0,
"error": "string",
"response": {
"lastseen": 0,
"mapstats": {
"maps": [
{
"tier": 0,
"modeid": 0,
"modename": "string",
"modecolor": "string",
"bonus": 0,
"name": "string",
"rank": 0,
"time": "string",
"num_completed": 0
}
],
"highest_tier": 0,
"num_beaten": 0,
"percent_completion": 0
},
"tag_color": "string",
"name": "string",
"rank": 0,
"avatar": "string",
"tag": "string",
"playtime": 0,
"percent": 0
}
}
]


And here is my java class:

package com.horizonservers.horizon;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.regex.Pattern;

import javax.net.ssl.HttpsURLConnection;


/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link MainFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link MainFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class MainFragment extends Fragment {


// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private static final Pattern delimeter = Pattern.compile(",\\s+");

private TextView mResult;

private OnFragmentInteractionListener mListener;

public MainFragment() {
// Required empty public constructor
}

/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment MainFragment.
*/
// TODO: Rename and change types and number of parameters
public static MainFragment newInstance(String param1, String param2) {
MainFragment fragment = new MainFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}

new PostDataTask().execute("https://www.horizonservers.net/api/v1/PlayerInfo");


}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_main, container, false);
mResult = (TextView) v.findViewById(R.id.tv_result);
return v;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}


// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}

@Override
public void onDetach() {
super.onDetach();
mListener = null;
}

/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}

class PostDataTask extends AsyncTask<String, Void, String> {

ProgressDialog progressDialog;

@Override
protected void onPreExecute() {
super.onPreExecute();

}

@Override
protected String doInBackground(String... params) {

try {
return postData(params[0]);
} catch (IOException ex) {
return "Network error !";
} catch (JSONException ex) {
return "Data Invalid !";
}
}

@Override
protected void onPostExecute(String result) {

try {
JSONObject jsonObject = new JSONObject(result);

String NameInfo = jsonObject.getString("name");

JSONObject jsonObject1 = new JSONObject(NameInfo);

for(int i = 0; i < jsonObject1.length(); i++){
JSONObject jsonPart = new JSONObject();

//Log.i("response", jsonPart.getString("response"));
String newName = jsonPart.getString("name");
//mResult.setText(NameInfo);
mResult.setText(newName);
}


} catch (JSONException e) {
mResult.setText("Error!");
}
super.onPostExecute(result);


if (progressDialog != null) {
progressDialog.dismiss();
}
}


private String postData(String urlPath) throws IOException, JSONException {

StringBuilder result = new StringBuilder();
BufferedWriter bufferedWriter = null;
BufferedReader bufferedReader = null;

try {
//Create data to send to server
JSONObject dataToSend = new JSONObject();
dataToSend.put("apikey", "UPj07lqWdetOWrk9M8Ya9UZzeIAizjr4sYQRKzkHFYm1KaQDopytCFq9HHCerwNy");
dataToSend.put("steamid", "STEAM_0:1:90345825");
dataToSend.put("maptype", "surf");

//Initialize and config request, then connect to server.


URL url = new URL(urlPath);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(10000 /* milliseconds */);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true); //enable output (body data)
urlConnection.setRequestProperty("Content-Type", "application/json");// set header
urlConnection.connect();

//Write data into server
OutputStream outputStream = urlConnection.getOutputStream();
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write(dataToSend.toString());
bufferedWriter.flush();

//Read data response from server
InputStream inputStream = urlConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
result.append(line).append("&");
}
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
if (bufferedWriter != null) {
bufferedWriter.close();
}
}

return result.toString();

}
}


}

The specific part that prints the information to the screen is

@Override
protected void onPostExecute(String result) {

try {
JSONObject jsonObject = new JSONObject(result);

String NameInfo = jsonObject.getString("name");

JSONObject jsonObject1 = new JSONObject(NameInfo);

for(int i = 0; i < jsonObject1.length(); i++){
JSONObject jsonPart = new JSONObject();

//Log.i("response", jsonPart.getString("response"));
String newName = jsonPart.getString("name");
//mResult.setText(NameInfo);
mResult.setText(newName);
}


} catch (JSONException e) {
mResult.setText("Error!");
}
super.onPostExecute(result);


if (progressDialog != null) {
progressDialog.dismiss();
}
}


How can I parse these objects from the array/objects. I have already tried converting it to an array, but it becomes worse at that point. Thank you in advance for your help.

Answer

I'm not sure which data from your JSON response, you are trying to extract. But I think this example with Google Translate API will help you out.

JSON Response:

"data": {
    "translations": [
        {
            "translatedText": "Hallo Welt",
            "detectedSourceLanguage": "en"
        }
    ]
}

If I want to get the translatedText, "Hallo Welt", I do it like this:

public String parseJSONForTranslation(String jsonString) {
    try {
        JSONObject object = (JSONObject) new JSONTokener(jsonString).nextValue();
        return object.getJSONObject("data").getJSONArray("translations").
                getJSONObject(0).getString("translatedText");
    }
    catch (JSONException e) {
        return null;
    }
}

So as you can see, if you want to further extract information by going into the next "level" of your JSON response, you use either getJSONObject or getJSONArray (depending on if it's an array or not) until you reach the "level" where the data you want to extract is at. And you only use getString when you are at that last "level". Hopefully, this can help you out.