Populating Spinner with JSON in Android 4.2 using AsyncTask - android

I am currently trying to translate the code for the MainActivity of an app that I created in API10 into API 16. From what I have read, I have to start using ASyncTask to access a URI and display the information on my app. I managed to do that in 2.3, but after translating it to JSON, I am now facing some roadblocks.
Essentially, what the app does is that, it takes a manifest code i.e. WAMF33000 and at the click of a button, the Spinner is populated with the jobs contained in that manifest. As I am fairly new to the concept of ASyncTask, I would like to understand how my code applies to the theory behind ASyncTask.
Based on my code, I have some questions:-
i) Which of my code in the ASyncTask is the parameter that is being passed?
ii) What is the progress value in my AsyncTask?
iii) Finally, is my return value the ArrayList of ManifestItems?
As of the 2.3 version, I invoke the JSON twice - once to load the consignments within the Manifest, and the second time to load details of a consignment selected in the spinner.
The following is my code:
package com.signonglass;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.*;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
{
private final static String POD_URI = "http://192.168.0.105:8092/PodCore.svc";
private EditText evManifestCode;
private Spinner list_job;
private Button btnSubmit;
private String jobName;
private Button btnCons;
ArrayList<ManifestItemObj> jobList = new ArrayList<ManifestItemObj>();
ArrayList<ConsignmentItems> conItemList = new ArrayList<ConsignmentItems>();
Consignments retConsignment;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
evManifestCode = (EditText)findViewById(R.id.manifest);
btnSubmit = (Button)findViewById(R.id.btnSearchManifest);
list_job = (Spinner)findViewById(R.id.jobSpinner);
//tvView = (TextView)findViewById(R.id.deviceIdt);
//TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
//String IMEI_Number = telephonyManager.getDeviceId();
//tvView.setText("IMEI Number: " + IMEI_Number);
}
public class MyAsyncTask extends AsyncTask<String, Void, ArrayList<ManifestItemObj>>
{
protected void onPreExecute()
{
}
protected void onPostExecute(ArrayList<ManifestItemObj> jobList)
{
}
#Override
protected ArrayList<ManifestItemObj> doInBackground(String... params)
{
//http get request
HttpGet request = new HttpGet(POD_URI + "/getJobs/" + evManifestCode.getText().toString());
//set the hedear to get the data in JSON format
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
DefaultHttpClient client = new DefaultHttpClient();
String theString = new String("");
try
{
//get the response
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
is.close();
theString = builder.toString();
JSONObject jobsJSON = new JSONObject(theString);
JSONArray jobs = jobsJSON.getJSONArray("getJobsResult");
for(int i = 1; i < jobs.length(); i++)
{
JSONObject mit = jobs.getJSONObject(i);
ManifestItemObj mi = new ManifestItemObj();
mi.ManifestItemID = mit.getInt("ManifestItemID");
mi.JobType = mit.getString("JobType");
mi.FKID = mit.getInt("FKID");
jobList.add(mi);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return jobList;
}
}
/*private void showToast(String msg)
{
// TODO Auto-generated method stub
Toast.makeText(this, "Toast: " + msg, Toast.LENGTH_LONG).show();
}*/
public void onViewConsignment(View view)
{
ShowItemsOfManifest(retConsignment);
}
public Consignments getConsignmentManifest(String consignment)
{
Consignments con = new Consignments();
try
{
DefaultHttpClient client = new DefaultHttpClient();
String theString = new String("");
//http get request
HttpGet request = new HttpGet(POD_URI + "/getJobDetails/" + consignment);
//set the hedear to get the data in JSON format
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
//get the response
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
{
builder.append(line);
}
is.close();
theString = builder.toString();
JSONObject conJSON = new JSONObject(theString);
JSONArray cons = conJSON.getJSONArray("getJobDetailsResult");
for(int i = 0; i < cons.length(); i++)
{
JSONObject cObj = cons.getJSONObject(i);
con.ConsignmentID = cObj.getInt("ConsignmentID");
con.ConsignmentCreationDate = cObj.getString("ConsignmentCreationDate");
con.ConsignmentCustRef = cObj.getString("ConsignmentCustRef");
con.OrderNo = cObj.getString("OrderNo");
con.ConsignmentActive = cObj.getBoolean("ConsignmentActive");
con.JobType = cObj.getString("JobType");
//Client object
JSONObject clObj = cObj.getJSONObject("Client");
Clients cl = new Clients();
cl.ClientId = clObj.getInt("ClientID");
cl.ClientName = clObj.getString("ClientName");
con.Clients = cl;
//ShipTo object
JSONObject stObj = cObj.getJSONObject("ShipTo");
ShipTo sto = new ShipTo();
sto.ShipToId = stObj.getInt("ShipToId");
sto.ShipToName = stObj.getString("ShipToName");
sto.ShipToAddress1 = stObj.getString("ShipToAddress1");
sto.ShipToAddress2 = stObj.getString("ShipToAddress2");
sto.ShipToCity = stObj.getString("ShipToCity");
sto.ShipToPostcode = stObj.getString("ShipToPCode");
sto.ShipToState = stObj.getString("ShipToState");
con.ShipTo = sto;
//FreightZone object
JSONObject fzObj = cObj.getJSONObject("FreightZone");
FreightZones fz = new FreightZones();
fz.FreightZoneID = fzObj.getInt("FreightZoneId");
fz.FreightZone = fzObj.getString("FreightZone");
con.FreightZone = fz;
JSONArray conItems = cObj.getJSONArray("ConsignmentItems");
for(int m = 0; m < conItems.length(); m++)
{
JSONObject cit = conItems.getJSONObject(m);
ConsignmentItems ci = new ConsignmentItems();
ci.ConsignmentItemID = cit.getInt("ConsignmentItemsID");
ci.Quantity = cit.getInt("QTY");
//get Product from ConsignmentItems
JSONObject pro = cit.getJSONObject("Products");
Products prod = new Products();
prod.ProductId = pro.getInt("ProductID");
prod.ProductModel = pro.getString("ProductModel");
prod.ItemsPerCarton = pro.getInt("PerCarton");
prod.ProductDescription = pro.getString("Description");
prod.Height = (float) pro.getDouble("Height");
prod.Length = (float) pro.getDouble("Length");
prod.Width = (float) pro.getDouble("Width");
prod.Cubic = (float) pro.getDouble("Cubic");
ci.Product = prod;
conItemList.add(ci);
con.ConsignmentItems = conItemList;
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
return con;
}
public void ShowItemsOfManifest(Consignments consignments)
{
Bundle bundle = new Bundle();
Intent newIntent = new Intent(this.getApplicationContext(), ConActivity.class);
newIntent.putExtras(bundle);
newIntent.putExtra("Consignment", consignments);
this.startActivity(newIntent);
}
public void onSearchClick(View view)
{
new MyAsyncTask().execute();
ManifestItemAdapter mia = new ManifestItemAdapter(MainActivity.this, android.R.layout.simple_spinner_item, jobList);
list_job.setAdapter(mia);
}
}
I look forward to understanding more about ASyncTask through your constructive comments on my code. Thanks ahead for helping me improve my code and my understanding of Android, guys! :)
PS: Please let me know if you need any more code to work with. I will update my post with more information as necessary. Cheers!

The point behind AsyncTask is to allow you to run background work on a separate thread such as networking stuff so you don't hold up the UI and users can still do things while data is being downloaded.
Which of my code in the ASyncTask is the parameter that is being passed?
You currently are not passing any params to the AsyncTask
new MyAsyncTask().execute(); // you would put params in here if needed such as a URL, String, etc...
What is the progress value in my AsyncTask?
As far as I can tell, you don't have one. If you wanted to you could use publishProgress(value) and that would be sent to onProgressUpdate() to update things like files downloaded, time of progression, time left, etc...
Finally, is my return value the ArrayList of ManifestItems?
you are returning jobList so that is what will get sent to onPostExecute() to do what you need with it
Note: One of the most important things to understand about AsyncTask is that you can't update the UI from doInBackground() so you must do this in one of the other AsyncTask methods or pass values back to a UI function. Also, AsyncTask works differently in 2.3 than it does in 3.0 and beyond. They don't run in parallel any more but put into a queue. So you may want to read about executeOnExecutor() if you want them to run in parallel in 4.2. I hope this answers your questions
AsyncTask
executeOnExecutor()(http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)
A couple other things I see is that you will want to add the #Override annotation to the implemented methods as well as super calls.

Related

get JSON Array from local server in android 6.0 with HttpURLConnection

I am trying to get a JSON Array from this local server for five days:
localhost/match_picture/service.php?action=read
and i can't do it !!
I search it in google and read too many documentations !
here is my code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class WebService {
public static String readUrl(String server_url) {
BufferedReader bufferedReader = null;
try {
URL url = new URL(server_url);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json+"\n");
}
return sb.toString();
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
and it's Main_Activity:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class Activity_main extends AppCompatActivity {
private ArrayList<StructAcount> netAcount = new ArrayList<StructAcount>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String result= WebService.readUrl("http://localhast/match_picture/service.php?action=read");
if (result != null) {
try {
JSONArray tasks = new JSONArray(result);
for (int i=0; i<tasks.length(); i++) {
StructAcount acount= new StructAcount();
JSONObject object = tasks.getJSONObject(i);
acount.id = object.getLong("user_id");
acount.name = object.getString("user_name");
acount.email = object.getString("user_email");
netAcount.add(acount);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
for (StructAcount acount: netAcount) {
Toast.makeText(Activity_main.this, "username: " + acount.name + "\n" + "useremail: " + acount.email , Toast.LENGTH_SHORT).show();
}
}
}
it is runing on emulator and crashes in this line:
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
and i dont know why ...
I am Searching for five days!!!!
I can do it with HttpClient
but i want to be update
I saw a vidoe in youtube that create a class in Main_Activity extends AsyncTask and make connenction in doInBackground(String... params). I try that and that works correcly. but because I want to do it in anoder class (WebService) and I dont know how can i sent result to Main_Activity , I remove that class extended from AsyncTask.
thank's for your help
sorry for my poor english
You have a NetworkOnMainThreadException to begin with.
And your app crashes.
Google how to solve it.

Android:Dynamically changing the height of the image view according to the received json data

I am accessing a mysql database table to show the tank level .I need to display the value in an image view using a rectangle.Each time value of the level changes I need to change the height of the rectangle.How is it possible in android.In the below code container 1 and container 2 is the variable which stores the level data.How to access this data and change the height of the image view.
package com.example.tg.mysmartcontainer;
import android.os.AsyncTask; import android.os.Bundle; import
android.support.v7.app.ActionBarActivity; import
android.widget.ListAdapter; import android.widget.ListView; import
android.widget.SimpleAdapter; import android.os.Handler; import
org.apache.http.HttpEntity; import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost; import
org.apache.http.impl.client.DefaultHttpClient; import
org.apache.http.params.BasicHttpParams; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONObject;
import java.io.BufferedReader; import java.io.InputStream; import
java.io.InputStreamReader; import java.util.ArrayList; import
java.util.HashMap;
public class MainActivity extends ActionBarActivity {
String myJSON;
Handler mHandler;
private static final String TAG_RESULTS = "result";
private static final String TAG_timeStamp = "timeStamp";
private static final String TAG_container1 = "container1";
private static final String TAG_container2 = "container2";
JSONArray container = null;
ArrayList<HashMap<String, String>> ContainerList;
ListView list;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.listView);
ContainerList = new ArrayList<HashMap<String, String>>();
final Handler handler = new Handler();
Runnable refresh = new Runnable() {
#Override
public void run() {
getData();
handler.postDelayed(this, 0);
}
};
handler.postDelayed(refresh, 0);
//getData();
}
public void getData() {
class GetDataJSON extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("http://smartgrocer.000webhostapp.com/get_data.php");
// Depends on your web service
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null;
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
// Oops
} finally {
try {
if (inputStream != null) inputStream.close();
} catch (Exception squish) {
}
}
return result;
}
#Override
protected void onPostExecute(String result) {
myJSON = result;
showList();
}
}
GetDataJSON g = new GetDataJSON();
g.execute();
}
protected void showList() {
try {
JSONObject jsonObj = new JSONObject(myJSON);
container = jsonObj.getJSONArray(TAG_RESULTS);
if(ContainerList!=null&&ContainerList.size()>0)
ContainerList.clear();
for (int i = 0; i < container.length(); i++) {
JSONObject c = container.getJSONObject(i);
String timeStamp = c.getString(TAG_timeStamp);
String container1 = c.getString(TAG_container1);
String container2 = c.getString(TAG_container2);
HashMap<String, String> container = new HashMap<String, String>();
container.put(TAG_timeStamp, timeStamp);
container.put(TAG_container1, container1);
container.put(TAG_container2, container2);
ContainerList.add(container);
}
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, ContainerList, R.layout.list_item,
new String[]{TAG_timeStamp, TAG_container1, TAG_container2},
new int[]{R.id.timeStamp, R.id.container1, R.id.container2}
);
list.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
to set the height of the ImageView:
image_view.getLayoutParams().height = 20;
Hope this helps.
Important. If you're setting the height after the layout has already been 'laid out', make sure you also call:
image_view.requestLayout()
Change the height of the imageView according to the current value :
tankImageView.setHeight((int)(currentValue / maxValue));

How to reuse data from a JSONArray which got data in onPostExecute

this is my code for getting data from a PHP site into a ListView.
package be.pressd.arrangementen;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
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 org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
Button fetch;
EditText et;
String aantalPersonen;
private ListView lv;
private ArrayAdapter<String> listAdapter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fetch = (Button) findViewById(R.id.fetchButton);
et = (EditText) findViewById(R.id.aantalPersonen);
// Find the ListView resource.
lv = (ListView) findViewById(R.id.arrangementenLijst);
listAdapter = new ArrayAdapter<String>(this, R.layout.line_row);
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Toast.makeText(getApplicationContext(), "Click nummer " + position, Toast.LENGTH_LONG).show();
String arrangement = (String) lv.getItemAtPosition(position);
// Launching new Activity on selecting single List Item
Intent i = new Intent(getApplicationContext(), ArrangementItem.class);
// sending data to new activity
i.putExtra("arrangement", arrangement);
startActivity(i);
}
});
fetch.setOnClickListener(this);
}
class task extends AsyncTask<String, String, Void>
{
private ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
InputStream is = null ;
String result = "";
protected void onPreExecute() {
progressDialog.setMessage("Fetching data...");
progressDialog.show();
progressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface arg0) {
task.this.cancel(true);
}
});
}
#Override
protected Void doInBackground(String... params) {
String url_select = "http://mywebsite/thephpform.php?aantpers=" + aantalPersonen;
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
try
{
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
//read content
is = httpEntity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection "+e.toString());
}
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = "";
while((line=br.readLine())!=null)
{
sb.append(line+"\n");
}
is.close();
result=sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result "+e.toString());
}
return null;
}
protected void onPostExecute(Void v) {
try
{ listAdapter.clear();
JSONArray Jarray = new JSONArray(result);
for(int i=0; i < Jarray.length(); i++)
{
JSONObject Jasonobject = null;
Jasonobject = Jarray.getJSONObject(i);
String name = Jasonobject.getString("naam");
listAdapter.add(name);
}
this.progressDialog.dismiss();
lv.setAdapter( listAdapter);
} catch (Exception e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.fetchButton :
aantalPersonen = et.getText().toString();
if (aantalPersonen.trim().equals("")) {
Toast.makeText(this, "Gelieve het aantal personen in te geven", Toast.LENGTH_SHORT).show();
return;
}
else
{
new task().execute();
break;
}
}
}
}
It is my first Android code ever, so besides my question it is possible that this code can be made better.
What I would like to do is to show ALL data, nicely, which was gotten from the website. But, as a ListView can not contain the ID and other data, I'm wondering if I can reuse the data in the JSONObject to be shown in next screen (on click of ListView item) ?
Greetings and thanks in advance,
Davy
Create variables for which you want to store information and loop through JsonArray and get each JsonObject and parse/extract information that you need and store it in variables.
here is sample code to iterate JsonArray //Here response is JsonArray
Create Simple class like
public class PersonInfo{
String name,address; //Create variables of your requirement.
//Add Getter Setter Methods for these variables
}
//End of class PersonInfo
ArrayList<PersonInfo> persons = new ArrayList<PersonInfo>();
PersonInfo person;
JSONObject product;
try
{
for (int j = 0; j < response.length(); j++)
{
person = new Person();
product = response.getJSONObject(j);
person.name = product.getString("JSON_KEY_NAME"); //like these assign values to each variable of PersonInfo class
//Other values initialization
}
persons.add(person); // Add PersonInfo object to ArrayList
}
catch (Exception e)
{
e.printStackTrace();
}
something like that .
you can get json values upon your requirments.
This is just sample code .
You could
save the JSON and parse it again later (you would have to do a lot of parsing)
save the data you parse from the json
in sharedpreferences (only if small amount of data)
in a local sqlite db (probably cleanest approach with best user experience, but a lot of work since you have to create a class that does all the db CRUD operations)
It depends on your data. For user preferences I would use SharedPreferences, for larger amounts a local DB. Also you could create some objects to store the data you need, maybe as signletons or something, and parse the stored JSONs everytime you start the app.
See the google docs on data storage for reference.
To save data you are getting in background task you have to use shared preferences.
Refer this link to get details about shared preferences.
To pass data to next page you have to use following code :
Intent intent = new Intent( currentActivity.this, NextActivity.class);
intent.putExtra("key", "value");
startActivity(intent);
On nextActivity.java add following code inside onCreate()
Intent currentPageIntent = getIntent();
String strValue = currentPageIntent.getStringExtra("key");
If you are having any other data type than string you have to use other method instead of getStringExtra()
To get id of item clicked, you can use following code :
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
try {
JSONArray jsonArray = new JSONArray(jsonData);
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
if (i == id) {
//Add your code here
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally { }
}
});
Note that you have to process jsonData on your own. This is just sample code I used in one of my porjects.

Getting json type mismatch error

I am new to android development and am trying to work with json data. I followed the web page "
http://hmkcode.com/android-parsing-json-data/" to make a simple app to get and display json. It works fine with the tutorial json web site. But when I change the url to point to my website I get an exception error on the line "JSONObject json = new JSONObject(result);"
03-15 08:56:10.518: W/System.err(1330): org.json.JSONException: Value <?xml of type
java.lang.String cannot be converted to JSONObject
03-15 08:56:10.528: W/System.err(1330): at org.json.JSON.typeMismatch(JSON.java:111)
03-15 08:56:10.528: W/System.err(1330): at org.json.JSONObject.<init>(JSONObject.java:159)
03-15 08:56:10.528: W/System.err(1330): at org.json.JSONObject.<init>(JSONObject.java:172)
When I display the string I get it looks like this (almost, I had trouble formatting, the mgmtresponse line is all one line, I also blocked out the ip address):
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<mgmtResponse
responseType="operation"requestUrl="https://128.205.x.xxx/webacs/api/v1/op/info/version"
rootUrl="https://128.205.x.xx/webacs/api/v1/op">
-<versionInfoDTO>
<result>2.0.0.0.294</result>
</versionInfoDTO>
</mgmtResponse>
Here is the main section of code. As you can see I tried a bunch of things and commented out a bunch of things to get down to the problem. I am stuck at the point where I can not take my input and convert it to a json object. I think I need to format the response some how but I just can not figure out what is wrong.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
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.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Base64;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText etResponse;
TextView tvIsConnected;
static TextView response_code;
static String httpcode;
static String version;
#Override
// oncreate is called when activity is created
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get reference to the views
etResponse = (EditText) findViewById(R.id.etResponse);
tvIsConnected = (TextView) findViewById(R.id.tvIsConnected);
response_code = (TextView) findViewById(R.id.response_code);
// check if you are connected or not
if(isConnected()){
tvIsConnected.setBackgroundColor(0xFF00CC00);
tvIsConnected.setText("network is connected");
}
else{
tvIsConnected.setText("network is NOT connected");
}
// call AsynTask to perform network operation on separate thread
new HttpAsyncTask().execute("https://128.205.x.xx/webacs/api/v1/op/info/version");
// new HttpAsyncTask().execute("https://hmkcode.appspot.com/rest/controller/get.json");
}
public static String GET(String url){
InputStream inputStream = null;
String result = "";
try {
// create HttpClient
HttpClient httpclient = new MyHttpClient();
HttpGet request = new HttpGet(url);
request.setHeader("Authorization", "Basic " + Base64.encodeToString
("username:password".getBytes(), Base64.NO_WRAP));
// make GET request to the given URL
HttpResponse httpResponse = httpclient.execute(request);
final int StatusCode = httpResponse.getStatusLine().getStatusCode();
String st=String.valueOf(StatusCode);
httpcode = st;
//HttpResponse httpResponse = HttpClient.execute(new HttpGet(url));
// receive response as inputStream
//HttpEntity entity = httpResponse.getEntity();
//result = EntityUtils.toString(entity);
inputStream = httpResponse.getEntity().getContent();
// convert inputstream to string
if(inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
return result;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader
(inputStream,"iso-8859-1"),8);
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line+"\n";
inputStream.close();
return result;
}
public boolean isConnected(){
ConnectivityManager connMgr = (ConnectivityManager) getSystemService
(Activity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
return true;
else
return false;
}
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
return GET(urls[0]);
}
// onPostExecute displays the results of the AsyncTask.
// displays results to Edittext and displays recieved to toast
#Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), "Received!", Toast.LENGTH_LONG).show();
etResponse.setText(result);
response_code.setText(httpcode);
try {
//etResponse.setText(result);
JSONObject json = new JSONObject(result);
//etResponse.setText(json.toString(1));
//JSONObject mgmtResponse =
// new JSONObject(json.getString("mgmtResponse"));
//JSONObject versionInfoDTO =
// new JSONObject(mgmtResponse.getString("versionInfoDTO"));
version = "NCS-Version";
//
//JSONArray articles = json.getJSONArray("articleList"); //get articles array
//str += "articles length = "+json.getJSONArray("articleList").length();
//str += "\n--------\n";
//str += "names: "+articles.getJSONObject(0).names(); //get first articles keys
//str += "\n--------\n";
//str += "url: "+articles.getJSONObject(0).getString("url"); //return an article url
//String str = "NCS Version";
//version += versionInfoDTO.getJSONObject("result");
etResponse.setText(version);
// not - etResponse.setText(json.toString(1));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//etResponse.setText(version);
}
}
}
As Rashmi points out, you are receiving data in XML-format, and attempting to parse it as JSON-format, which is giving you an error. The format of the data can usually be specified in the request URL.
EDIT
Your are using the URL https://128.205.x.xx/webacs/api/v1/op/info/version and I don't know what that is, if it's your own server or not, but usually, APIs provide both XML and JSON formats, which could look something like this:
https://example.com:2087/xml-api/functionname
for XML and
https://example.com:2087/json-api/functionname
for JSON
Some webservices will allow/require you to specify "application/json" as the accept header, so in addition to this:
HttpGet request = new HttpGet(url);
request.setHeader("Authorization", "Basic " + Base64.encodeToString
("username:password".getBytes(), Base64.NO_WRAP));
Say what you want back:
request.setHeader("Accept", "application/json");
And, if required, what you are supplying:
request.setHeader("Content-type", "application/json");

JSON parsing error - not parse in google API 4.1 jelly bean

i am working on an app using json parsing...in this parsing is done by json of the given url.
As i run my project on emulator having target = "Google APIs (Google Inc.) - API level 10"
then it runs properly and shows needed results from the target url.
but when run my project on emulator having target = "Google APIs (Google Inc.) - API level 16"
then it shows error and it never parse the given url data and get force close.
i want to make app which run on every API level.
please help...
here's my code:
json parser class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONArray jObj = null;
static String json = "";
static String req = "POST";
// constructor
public JSONParser() {
}
public JSONArray getJSONFromUrl(String url, String method) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = null;
if(method == req) {
HttpPost httpC = new HttpPost(url);
httpResponse = httpClient.execute(httpC);
}else {
HttpGet httpC = new HttpGet(url);
httpResponse = httpClient.execute(httpC);
}
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONArray(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Another class using json parser class snd fetch data:
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
public class showData extends ListActivity{
public static String url = "http://something/something/";
public static final String TAG_A = "a";
public static final String TAG_B = "b";
public static final String TAG_C = "c";
public static final String TAG_D = "d";
public static final String TAG_E = "e";
public static final String TAG_F = "f";
public static final String GET = "get";
JSONArray Data1 = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
EditText editext_text = (EditText) findViewById(R.id.et);
String urlnew = url + editext_text.getText().toString();
Log.d("url", urlnew);
JSONParser jParser = new JSONParser();
// getting JSON string from URL
area1 = jParser.getJSONFromUrl(urlnew, GET);
Log.d("Json String", area1.toString());
try {
for(int i = 0; i < area1.length(); i++){
JSONObject c = area1.getJSONObject(i);
// Storing each json item in variable
String a = c.getString(TAG_A);
String b = c.getString(TAG_B);
String c = c.getString(TAG_C);
String d = c.getString(TAG_D);
String e = c.getString(TAG_E);
HashMap<String,String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_A, a);
map.put(TAG_B, b);
map.put(TAG_C, c);
map.put(TAG_D, d);
map.put(TAG_E, e);
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(this, contactList,
R.layout.list_item_area,
new String[] { TAG_B, TAG_A, TAG_C, TAG_D, TAG_E }, new int[] {
R.id.b, R.id.a, R.id.c, R.id.d, R.id.e });
setListAdapter(adapter);
}
}
You are getting a NetworkOnMainThreadException because as the name is self-explaining, you are doing network request on UI Thread that will make your application laggy and create an horrible experience.
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or
higher. Applications targeting earlier SDK versions are allowed to do
networking on their main event loop threads, but it's heavily
discouraged. See the document Designing for Responsiveness.
You should use Threads or AsyncTask, do you need some explanations on how to use them?
private class NetworkTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//DO YOUR STUFF
}
#Override
protected void onPostExecute(String result) {
//Update UI
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
This is Network On Main Thread Exception, You have to use Thread for network connection, because the main thread is UI thread will not give any response for Network connection. Use separate thread for network connection

Categories

Resources