This question already has answers here:
Sending and Parsing JSON Objects in Android [closed]
(11 answers)
Closed 7 years ago.
I am building an Android application that receives some data in JSON format. At the moment the result is very ugly. I want to display this data neatly in multiple TextViews in my application but I am not to sure how to do it. Source code below.
Main.java
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Main extends Activity implements OnClickListener {
TextView txt1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.my_button).setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
Button b = (Button)findViewById(R.id.my_button);
b.setClickable(false);
new LongRunningGetIO().execute();
}
private class LongRunningGetIO extends AsyncTask <Void, Void, String> {
protected String getASCIIContentFromEntity(HttpEntity entity) throws IllegalStateException, IOException {
InputStream in = entity.getContent();
StringBuffer out = new StringBuffer();
int n = 1;
while (n>0) {
byte[] b = new byte[4096];
n = in.read(b);
if (n>0) out.append(new String(b, 0, n));
}
return out.toString();
}
#Override
protected String doInBackground(Void... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("https://api.myjson.com/bins/363s3");
String text = null;
try {
HttpResponse response = httpClient.execute(httpGet, localContext);
HttpEntity entity = response.getEntity();
text = getASCIIContentFromEntity(entity);
} catch (Exception e) {
return e.getLocalizedMessage();
}
return text;
}
protected void onPostExecute(String results) {
if (results!=null) {
txt1 = (TextView)findViewById(R.id.textView1);
txt1.setText(results);
}
Button b = (Button)findViewById(R.id.my_button);
b.setClickable(true);
}
}
}
i use retrofit for asynchronous execution use Callback
If what u mean is how to structure the data u receive from the json then you should look into json formatting frameworks (like 'Jackson' or 'Gson' or others).
If what u mean is how to make the textual json appear neatly in a textbox, jackson also appears to have an option to print the json neatly (try this: http://www.mkyong.com/java/how-to-enable-pretty-print-json-output-jackson/ )
What about trying something like,
JSONObject jsonObject = new JSONObject(jsonString);
By the way, Volley is a good library for any kind of requests.
Related
I have a MySQL database on a webserver and I read the data from this database in my application, but after I read the variables I can't use the "volt" variable outside the onPostExecute. I try t use adapter, but i can't use the data in the adapter like a intiger variable, just i can add to listview. So far i Don't find a solution for my problam.
I hope you can help me.
package com.example.wifis;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayAdapter<String> adapter;
// int tomb []={};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.list_item);
adapter= new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
listView.setAdapter(adapter);
new Conection().execute();
}
class Conection extends AsyncTask<String, String, String>{
#Override
public String doInBackground(String... strings) {
String result="";
String host="http://localhost/store/cars.php";
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(host));
HttpResponse response = client.execute(request);
BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer stringBuffer= new StringBuffer("");
String line = "";
while ((line = reader.readLine()) !=null ){
stringBuffer.append(line);
break;
}
reader.close();
result = stringBuffer.toString();
}
catch (Exception e){
return new String("There exeption: "+ e.getMessage());
}
return result;
}
#Override
public void onPostExecute(String result){
// Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
JSONObject jsonResult = null;
try {
jsonResult = new JSONObject(result);
int success = jsonResult.getInt("success");
if(success==1){
JSONArray cars = jsonResult.getJSONArray("cars");
JSONObject car = cars.getJSONObject(0);
int id = car.getInt("id");
int volt = car.getInt("szam");
String line = id + "-" + volt;
adapter.add(line);
// tomb[0]=szam;
}else{
Toast.makeText(getApplicationContext(), "NOT OK ", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
As I have tried to explain in my post here
the values you're trying to access aren't synchronous, meaning that your code does not execute top down. The AsyncTask returns a value at some point. we don't know when that will be, but when it returns the value, you'll have access to it within onPostExecute. this means that you can make use of the values as they are received there and only there, as that is the only place where you'll actually receive those values.
to get this value returned to your main activity, you can do something like this :
create an interface
public interface MyCallback {
void myResult(YourResultType output); //here, i believe this will be string for your specific case
}
This interface allows us to move the value we receive to another class when it's received
Next,
Go to your AsyncTask class, and declare interface MyCallback as a variable :
public class MyAsyncTask extends AsyncTask<String, String, String> {
public MyCallback callback = null;
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
}
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
now for your main activity:
public class MainActivity implements MyCallback {
MyAsyncTask asyncTask = new MyAsyncTask();
#Override
public void onCreate(Bundle savedInstanceState) {
//set your listener to this class
asyncTask.callback = this;
//execute the async task
asyncTask.execute();
}
//this overrides the implemented method from asyncTask
#Override
void myResult(YourResultType output){
//Here you will receive the result returned from the async task
}
}
please also note that async tasks are deprecated
also note, my java is quite rusty, I am fortunate enough to only use kotlin these days, feel free to correct me on any mistakes :)
This question already has answers here:
Convert JSON String to Pretty Print JSON output using Jackson
(11 answers)
Closed 6 years ago.
I have an API in JSON , my json datas are displayed raw on my android application , i want them to be displayed in pretty print format like this
Not like this
This is my java code :
package com.example.cbmedandroid;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.my_button).setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
Button b = (Button)findViewById(R.id.my_button);
b.setClickable(false);
new LongRunningGetIO().execute();
}
private class LongRunningGetIO extends AsyncTask <Void, Void, String> {
protected String getASCIIContentFromEntity(HttpEntity entity) throws IllegalStateException, IOException {
InputStream in = entity.getContent();
StringBuffer out = new StringBuffer();
int n = 1;
while (n>0) {
byte[] b = new byte[4096];
n = in.read(b);
if (n>0) out.append(new String(b, 0, n));
}
return out.toString();
}
#Override
protected String doInBackground(Void... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://10.0.2.2:8000/api/horaire.json");
String text = null;
try {
HttpResponse response = httpClient.execute(httpGet, localContext);
HttpEntity entity = response.getEntity();
text = getASCIIContentFromEntity(entity);
} catch (Exception e) {
return e.getLocalizedMessage();
}
return text;
}
protected void onPostExecute(String results) {
if (results!=null) {
EditText et = (EditText)findViewById(R.id.my_edit);
et.setText(results);
}
Button b = (Button)findViewById(R.id.my_button);
b.setClickable(true);
}
}
}
How to do that ?
Thanks
You need to use a JSON library like Jackson or GSON in order to pretty print your output. For an example with Jackson take a look at the answer here.
I am trying to get some data from a webservice, in my android app.
The code I am using is this:
#Override
protected String doInBackground(String... params) {
String highScore = null;
int points = 0;
try {
URI uri = new URI("http://vestsoft.somee.com/api/scores");
URL website = new URL(uri.toASCIIString());
InputStream inputStream = website.openStream();
InputSource input = new InputSource(inputStream);
SAXParserFactory saxp = SAXParserFactory.newInstance();
SAXParser sp = saxp.newSAXParser();
XMLReader xmlReader = sp.getXMLReader();
HighScoreHandler handler = new HighScoreHandler();
xmlReader.setContentHandler(handler);
xmlReader.parse(input); // Here is an exception thrown
highScore = handler.highScore.getUserName();
points = handler.highScore.getPoints();
} catch (Exception e) {
e.printStackTrace();
}
return highScore + " " + points;
}
I get an exception saying:
"At line 1, column 0: syntax error"
I don't know what I am doing wrong.
As you can see, the API I get my data from is:
http://vestsoft.somee.com/api/scores
Your XML lacks the correct header:
<?xml version="1.0" encoding="UTF-8"?>
Put that string at the top of your XML file and SAX Parser will stop bothering.
There are some really nice open source XML parsing tools out there to make this a lot easier. For example, to solve this with Simple XML, I would do it like this:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.squareup.okhttp.OkHttpClient;
public class MainActivity extends Activity {
public static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
URL website = new URL("http://vestsoft.somee.com/api/scores");
OkHttpClient client = new OkHttpClient();
HttpURLConnection conn = client.open(website);
conn.addRequestProperty("Accept", "application/xml");
InputStream stream = conn.getInputStream();
Serializer serializer = new Persister();
ArrayOfScore scoreArray = serializer.read(ArrayOfScore.class, stream);
// do something with the ArrayScore object here
} catch (Exception err) {
Log.i(TAG, err.toString());
}
}
};
new Thread(r).start();
}
});
}
}
This references two other classes, the XML annotated java classes. They are:
import java.util.List;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
#Root
public class ArrayOfScore {
#ElementList(inline=true,required=false)
private List<Score> scores;
public List<Score> getScores() {
return scores;
}
}
And:
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
#Root(name="Score")
public class Score {
#Element(name="Id",required=false)
Integer Id;
#Element(name="Name",required=false)
String Name;
#Element(name="Points",required=false)
String Points;
#Element(name="dateTime",required=false)
String dateTime;
}
With this simple model you can parse nearly any XML you encounter and get the parsing into first class objects automatically. There are similar classes for JSON such as Gson
I am not sure what causing the request not to execute. I was trying to call a WCF Restful service in android, and I receive the error message "Request Error". Looking at the example, I don't see any reason why this example should not work. See below:
Here is the .Net Service:
[ServiceContract]
public interface ISampleService
{
[OperationContract]
[WebInvoke(
Method="POST", UriTemplate="/Login", BodyStyle= WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string Login(string value);
}
public class SampleService : ISampleService
{
public string Login(string value)
{
string t = "";
try
{
//foreach (string s in value)
//{
// t = s;
//}
return t;
}
catch (Exception e)
{
return e.ToString();
}
}
}
Java:
package com.mitch.wcfwebserviceexample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONStringer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity implements OnClickListener {
private String values ="";
Button btn;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)this.findViewById(R.id.btnAccess);
tv = (TextView)this.findViewById(R.id.tvAccess);
btn.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
try
{
AsyncTaskExample task = new AsyncTaskExample(this);
task.execute("");
String test = values;
tv.setText(values);
} catch(Exception e)
{
Log.e("Click Exception ", e.getMessage());
}
}
public class AsyncTaskExample extends AsyncTask<String, Void,String>
{
private String Result="";
//private final static String SERVICE_URI = "http://10.0.2.2:8889";
private final static String SERVICE_URI = "http://10.0.2.2:65031/SampleService.svc";
private MainActivity host;
public AsyncTaskExample(MainActivity host)
{
this.host = host;
}
public String GetSEssion(String URL)
{
boolean isValid = true;
if(isValid)
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://10.0.2.2:65031/SampleService.svc/Login");
try
{
List<NameValuePair> value = new ArrayList<NameValuePair>(1);
value.add(new BasicNameValuePair("value", "123456"));
post.setEntity(new UrlEncodedFormEntity(value));
HttpResponse response = client.execute(post) ;
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line ="";
while((line = rd.readLine()) != null)
{
System.out.println(line);
}
}catch(Exception e)
{
Log.e("Error", e.getMessage());
}
}
return Result;
}
#Override
protected String doInBackground(String... arg0) {
android.os.Debug.waitForDebugger();
String t = GetSEssion(SERVICE_URI);
return t;
}
#Override
protected void onPostExecute(String result) {
// host.values = Result;
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
}
}
}
I finally got it to work they way that I want it to. The issue was that I was building the Array this way (see below section 1) and pass it to the JSONObject or JSONArray. I switched and build the Array using JSONArray and pass it to the JSONObject (see section 2). It works like a charm.
Section1: Wrong way to do it - (It may work this way if you were to look through the array and put them in a JSONArray. It's will be too much work when it can be done directly.)
String[][] Array = {
new String[]{"Example", "Test"},
new String[]{"Example", "Test"},
};
JSONArray jar1 = new JSONArray();
jar1.put(0, Array);
// Did not work
Section 2: The way I did it after long hours of trying and some very helpful tips and hints from #vorrtex.
**JSONArray jar1 = new JSONArray();
jar1.put(0, "ABC");
jar1.put(1, "Son");
jar1.put(2, "Niece");**
**JSONArray jarr = new JSONArray();
jarr.put(0, jar1);**
JSONArray j = new JSONArray();
j.put(0,"session");
JSONObject obj = new JSONObject();
obj.put("value", jarr);
obj.put("test", j);
obj.put("name","myName");
Log.d("Obj.ToString message: ",obj.toString());
StringEntity entity = new StringEntity(obj.toString());
Looking at the web service, and it has exactly what I was looking for.
Thanks for you help!!!!
Please refer to the following code which continuously calls a new AsyncTask. The purpose of the AsyncTask is to make an HTTP request, and update the string result.
package room.temperature;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class RoomTemperatureActivity extends Activity {
String result = null;
StringBuilder sb=null;
TextView TemperatureText, DateText;
ArrayList<NameValuePair> nameValuePairs;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TemperatureText = (TextView) findViewById(R.id.temperature);
DateText = (TextView) findViewById(R.id.date);
nameValuePairs = new ArrayList<NameValuePair>();
for (int i = 0; i < 10; i++) {
RefreshValuesTask task = new RefreshValuesTask();
task.execute("");
}
}
// The definition of our task class
private class RefreshValuesTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
InputStream is = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://mywebsite.com/roomtemp/tempscript.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}
catch(Exception e) {
Log.e("log_tag", "Error in http connection" + e.toString());
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
sb.append(reader.readLine());
is.close();
result=sb.toString();
}
catch(Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//System.out.println(result);
setValues(result);
}
}
public void setValues(String resultValue) {
System.out.println(resultValue);
String[] values = resultValue.split("&");
TemperatureText.setText(values[0]);
DateText.setText(values[1]);
}
}
The problem I am experiencing relates to the AsyncTask in some way or the function setValues(), but I am not sure how. Essentially, I want each call to the AsyncTask to run, eventually in an infinite while loop, and update the TextView fields as I have attempted in setValues. I have tried since yesterday after asking a question which led to this code, for reference.
Oh yes, I did try using the AsyncTask get() method, but that didn't work either as I found out that it is actually a synchronous call, and renders the whole point of AsyncTask useless.
Use publishProgress(), and onProgressUpdate() methods, to publish progress, while executing some task in doInBackground() method.
so change your code to following:
package room.temperature;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class RoomTemperatureActivity extends Activity {
String result = null;
StringBuilder sb=null;
TextView TemperatureText, DateText;
ArrayList<NameValuePair> nameValuePairs;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TemperatureText = (TextView) findViewById(R.id.temperature);
DateText = (TextView) findViewById(R.id.date);
nameValuePairs = new ArrayList<NameValuePair>();
RefreshValuesTask task = new RefreshValuesTask();
task.execute("");
}
// The definition of our task class
private class RefreshValuesTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
InputStream is = null;
for (int i = 0; i < 10; i++) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://mywebsite.com/roomtemp/tempscript.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}
catch(Exception e) {
Log.e("log_tag", "Error in http connection" + e.toString());
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
sb.append(reader.readLine());
is.close();
result=sb.toString();
publishProgress(result);
}
catch(Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
}
return result;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
setValues(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//System.out.println(result);
setValues(result);
}
}
public void setValues(String resultValue) {
System.out.println(resultValue);
String[] values = resultValue.split("&");
TemperatureText.setText(values[0]);
DateText.setText(values[1]);
}
}