I use below code to produce JSON string and parse it in php. I create an instace of this class and call setData method
//#PART1
String s = "{\"Category\":";
List<CategoryModel> pmo = new ArrayList<CategoryModel>();
pmo = CategoryModule.getAllRecords(c);
s += new JSONSerializer().serialize(pmo);
s += ",\"Data\":";
//#PART2
List<DataModel> amo = new ArrayList<DataModel>();
amo = DataModule.getAllRecords(c);
s += new JSONSerializer().serialize(amo);
s += "}";
I decode the result by below code
$categories = json_decode($data)->{'Category'};
$datas = json_decode($data)->{'Data'};
$username = "kkk";
foreach($categories as $category){
$id = $category->{'id'};
$name = $category->{'name'};
$sql = "INSERT INTO category (id,name,username) VALUES ('$id','$name','$username')";
$link->query($sql);
}
foreach($datas as $data){
$id = $data->{'id'};
$text = $data->{'text'};
$date = $data->{'date'};
$sql = "INSERT INTO data (id,text,date,username) VALUES ('$id','$name','$date','$username')";
$link->query($sql);
}
When I just use #PART1 to produce json string in the php code the decoding occurs in success. But when I add #PART2 to JSON string no one of them decodes successfully. I guess the problem can be from java code.
Please guide me
JSON result is http://aiga.ir/webservice/datastore/a.txt
I use this code for sending data
package ir.aiga.apps.network;
public class WebServiceComm extends AsyncTask<String, Void, Void> {
// Required initialization
private String Content;
private String Error = null;
private ProgressDialog Dialog;
private String data ="";
private boolean visible=true;
private InterFace doInPreExecute=new InterFace() {
#Override
public void doSomething() {
// TODO Auto-generated method stub
}
#Override
public void getResult(String output) {
// TODO Auto-generated method stub
}
#Override
public void getJSONArray(JSONArray array) {
// TODO Auto-generated method stub
}
};
private InterFace doInPostExecute=new InterFace() {
#Override
public void doSomething() {
// TODO Auto-generated method stub
}
#Override
public void getResult(String output) {
// TODO Auto-generated method stub
}
#Override
public void getJSONArray(JSONArray array) {
// TODO Auto-generated method stub
}
};
public WebServiceComm(Context context,String title,String text){
try {
data +="&" + URLEncoder.encode("data", "UTF-8") + "=";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Dialog=new ProgressDialog(context,ProgressDialog.STYLE_SPINNER);
Dialog.setTitle(title);
Dialog.setMessage(text);
}
public WebServiceComm(){
try {
data +="&" + URLEncoder.encode("data", "UTF-8") + "=";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setData(String data){
this.data+=data;
}
protected void onPreExecute() {
// NOTE: You can call UI Element here.
if(visible)
Dialog.show();
}
// Call after onPreExecute method
protected Void doInBackground(String... urls) {
/************ Make Post Call To Web Server ***********/
BufferedReader reader=null;
// Send data
try
{
// Defined URL where to send data
URL url = new URL(urls[0]);
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + "");
}
// Append Server Response To Content String
Content = sb.toString();
}
catch(Exception ex)
{
Error = ex.getMessage();
ex.printStackTrace();
}
finally
{
try
{
reader.close();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
/*****************************************************/
return null;
}
protected void onPostExecute(Void unused) {
// NOTE: You can call UI Element here.
if (Error != null) {
} else {
// Show Response Json On Screen (activity)
/****************** Start Parse Response JSON Data *************/
JSONObject jsonResponse;
try {
/****** Creates a new JSONObject with name/value mappings from the JSON string. ********/
jsonResponse = new JSONObject(Content);
/***** Returns the value mapped by name if it exists and is a JSONArray. ***/
/******* Returns null otherwise. *******/
JSONArray jsonMainNode = jsonResponse.optJSONArray("Android");
doInPostExecute.getJSONArray(jsonMainNode);
doInPostExecute.doSomething();
if(visible)
Dialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* #return the doInPreExecute
*/
public InterFace getDoInPreExecute() {
return doInPreExecute;
}
/**
* #param doInPreExecute the doInPreExecute to set
*/
public void setDoInPreExecute(InterFace doInPreExecute) {
this.doInPreExecute = doInPreExecute;
}
/**
* #return the doInPostExecute
*/
public InterFace getDoInPostExecute() {
return doInPostExecute;
}
/**
* #param doInPostExecute the doInPostExecute to set
*/
public void setDoInPostExecute(InterFace doInPostExecute) {
this.doInPostExecute = doInPostExecute;
}
/**
* #return the visible
*/
public boolean isVisible() {
return visible;
}
/**
* #param visible the visible to set
*/
public void setVisible(boolean visible) {
this.visible = visible;
}
}
please try to use this code for sending and receiving JSON with utf-8 encoding:
try {
URL url = new URL("your url");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(
conn.getOutputStream(), "UTF-8");
String request = "your json";
writer.write(request);
writer.flush();
System.out.println("Code:" + conn.getResponseCode());
System.out.println("mess:" + conn.getResponseMessage());
String response = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
response += line;
}
System.out.println(new String(response.getBytes(), "UTF8"));
writer.close();
reader.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
It's very bad to manually build JSON manually.
Using a JSON Mapper library
public class MyCustomModel {
public List<CategoryModel> Category;
public List<DataModel> Data;
public class CategoryModel{
//code here
}
public class DataModel{
//code here
}
}
Then use it GSON to serialize that object into JSON
MyCustomModel customModel = new MyCustomModel();
//populate object
//......
Gson gson = new Gson();
String json = gson.toJson(customModel);
Using standard library
JSONArray categoryArr = new JSONArray();
List<CategoryModel> categories = CategoryModule.getAllRecords(c);
for (CategoryModel category : categories) {
JSONObject categoryObj = new JSONObject();
categoryObj.put("class", category.getClass());
categoryObj.put("id", category.getId());
categoryObj.put("name", category.getName());
categoryArr.put(categoryObj);
}
Then do the same with the other list then combine both array
JSONObject jObject = new JSONObject();
jObject.put("Category", categoryArr);
jObject.put("Data", dataArr);
Related
Below is my code, lat_val and long_val is not getting updated with received value from JSON response in btnShowLoc(), it is referencing to the default value which is 0,0. I want the global variable to keep updating when ever referenced and updated with JSON response.
public class MainActivity extends Activity {
public static String lat_val = "0";
public static String long_val = "0";
public String readJSONFeed(String urlStr) {
StringBuilder stringBuilder = new StringBuilder();
try {
URL url = new URL(urlStr);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("SisApiKey", "4572c3c9-73cb-4958-9649-26c1e8df27e8");
urlConnection.setRequestProperty("SisSmartKey", "d1aebd25-774c-4e8a-b3a5-ee5a603cc603");
InputStream ins = urlConnection.getInputStream();
urlConnection.connect();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(ins));
String line;
while ((line = br.readLine()) != null) {
stringBuilder.append(line);
}
ins.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (java.net.MalformedURLException e) {
e.printStackTrace();
} catch (java.io.IOException e) {
e.printStackTrace();
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
public class ReadJSONFeedTask extends AsyncTask
<String, Void, String> {
protected String doInBackground(String... url) {
return readJSONFeed(url[0]);
}
protected void onPostExecute(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
//JSONObject flags = new JSONObject(jsonObject.getString("flag"));
JSONObject locationItems = new JSONObject(jsonObject.getString("response"));
//Log.v("Location Details :", locationItems.toString());
String []dev_loc = locationItems.toString().split("[\\s*,\\s*]");
MainActivity.lat_val = dev_loc[0]; //"12.9934136";
MainActivity.long_val = dev_loc[1]; //"80.2464206";
} catch (Exception e) {
Log.d("ReadJSONFeedTask", e.getLocalizedMessage());
}
}
}
public void btnGetDevLoc(View view) {
String sp_val = String.valueOf(spinner1.getSelectedItem());
new ReadJSONFeedTask().execute(
"http://15.153.133.160:21743/sis/sie/api/v1/applications/bb9f05fb-a796-4b75-9db7-c999360ad185/virtualobjects/d77d3905-aa77-41b9-9034-b0052bfde405?secondString=HWE_ASSET_ANDROID"); // + sp_val);
}
public void btnShowLoc(View view) {
//lat_val = "12.9934136";
//long_val = "80.2464206";
Intent in = new Intent(MainActivity.this, MapActivity.class);
Bundle bundle = new Bundle();
bundle.putString("latitude", MainActivity.lat_val);
bundle.putString("longitude", MainActivity.long_val);
in.putExtras(bundle);
startActivity(in);
}
With the few information you have shared, and given that
btnGetDevLoc() and btnShowLoc()are the functions executed when clicked on buttons in the application defined in activity_main.xml
and that
First btnGetDevLoc() is called then btnShowLoc()
the first thing that pops out in my mind is that the AsyncTask has not yet finished updating the String values, when you call btnShowLoc().
So, if btnGetDevLoc() and btnShowLoc() are called sequentially, like
... onClick() {
btnGetDevLoc();
btnShowLoc();
}
then it's most likely due to what I said above. Remember that AsyncTask runs asynchronously (as the name says...).
You can test this really small program.
public static double var1 = 0.0;
public static void main(String[] args) {
new Thread(() -> {
var1 = 1.0;
}).start();
System.out.println(var1);
}
It will almost always print 0.0, because the value of var1 is not updated yet when the main thread prints it.
What you should do is place your btnShowLoc() call at the end of onPostExecute(String). This guarantees that your method is called only after you have updated the new values.
I can't Understand, when the btnGetDevLoc() and btnShowLoc() called? Can you post your whole MainActivity?
Edit :
It's seems like you call btnShowLoc() before your AsyncTask finish its proccess.
You can change your code this way to make sure your btnShowLoc() called after your AsyncTask :
public class ReadJSONFeedTask extends AsyncTask
<String, Void, String> {
protected String doInBackground(String... url) {
return readJSONFeed(url[0]);
}
protected void onPostExecute(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
//JSONObject flags = new JSONObject(jsonObject.getString("flag"));
JSONObject locationItems = new JSONObject(jsonObject.getString("response"));
//Log.v("Location Details :", locationItems.toString());
String []dev_loc = locationItems.toString().split("[\\s*,\\s*]");
MainActivity.lat_val = dev_loc[0]; //"12.9934136";
MainActivity.long_val = dev_loc[1]; //"80.2464206";
btnShowLoc(dev_loc[0], dev_loc[1]);
} catch (Exception e) {
Log.d("ReadJSONFeedTask", e.getLocalizedMessage());
}
}
}
public void btnShowLoc(String latitude, String longitude) {
//lat_val = "12.9934136";
//long_val = "80.2464206";
Intent in = new Intent(MainActivity.this, MapActivity.class);
Bundle bundle = new Bundle();
bundle.putString("latitude", latitude);
bundle.putString("longitude", longitude);
in.putExtras(bundle);
startActivity(in);
}
I was using this in another place as async but I wanted to refactor to make it reusable, how can I reorganize the code in order to work as a consumable class?. It doesn't work if it's not async and the ip of the backend is well defined so it's not that. Any ideas?
public class HTTPRequestManager {
public static JSONArray fetchData(){
return null;
}
public static String postData(Context context, String url, String JSONData) {
return null;
}
/* #Override
protected Integer doInBackground(String... strings) {
try {
//1.create client Object
OkHttpClient client = new OkHttpClient();
//2.Define request being sent to server
RequestBody postData = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONData);
Request request = new Request.Builder()
.url(context.getResources().getString(R.string.backend_base_url) + url)
.post(postData)
.build();
//3.Transport the request and wait for response to process next
Response response = client.newCall(request).execute();
String resultData = response.body().string();
if (resultData.equals("OK")) {
} else {
//post failed
return "FAILED";
}
return resultData;
} catch (Exception e) {
Log.d("API_CONNECTION_ERROR", "Couldn't connect to the API");
return "API_CONNECTION_ERROR";
}
}*/
}
I used to have this annonymous class embeeded in another class and it works(it's a get request) but the problem is that it's not reusable in that way:
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
URL url = null;
#Override
protected void onPreExecute() {
getActivity().setProgressBarIndeterminateVisibility(true);
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
url = new URL (getResources().getString(R.string.backend_base_url) +
"api/flrcks/user/id/0/latitude/3000/longitude/300/within/9999999999999999999999999");
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result == 1) {
adapter = new MyRecyclerAdapter_Nearby(getActivity(), feedsList);
mRecyclerView.setAdapter(adapter);
checkAdapterIsEmpty();
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
t.setVisibility(View.VISIBLE);
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.getJSONArray("rows");
feedsList = new ArrayList<>();
JSONArray members;
for (int i = 0; i < posts.length(); i++) {
memberList = new ArrayList<>();
final JSONObject post = posts.optJSONObject(i);
members=post.getJSONArray("members");
final FeedItem item = new FeedItem();
//for (int i = 0; i < posts.length(); i++) {
//JSONObject post = posts.optJSONObject(i);
//FeedItem item = new FeedItem();
item.setId(post.optString("id"));
item.setTitle(post.optString("name"));
item.setDescription(post.optString("description"));
item.setPrivacy(post.optString("privacy_mode_description"));
item.setInitial_date(post.optString("initial_date"));
item.setThumbnail(post.optString("thumbnail"));
item.setColor_hex(post.optString("color_hex"));
item.setTag(post.optString("tag"));
item.setDistance(post.optInt("st_distance"));
//item.setThumbnail(post.optString("thumbnail"));
for(int k=0; k <members.length();k++)
{
MemberItem memberItem = new MemberItem();
JSONObject member = members.optJSONObject(k);
memberItem.setName(member.optString("name"));
memberItem.setUsername(member.optString("username"));
memberItem.setProfile_pic(member.optString("profile_pic"));
memberItem.setIs_moderator(member.optBoolean("is_moderator"));
memberItem.setFacebookId(member.optString("facebook_id"));
memberList.add(memberItem);
}
item.setMemberList(memberList);
feedsList.add(item);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
What changes do I need to make to put it in an isolated file to be consumed by the whole app like for example in a file called OkHTTPRequests.class???
Create an interface
public interface OnWebResponseListener {
void onWebResponse(CommonUtilities.services service, String result);
}
create a public enum for identifying service. in my case i created a CommonUtilities java where i declared
public enum services {
LOGIN
}
Your Common File
public class CallAddr extends AsyncTask<String, Void, String> {
CommonUtilities.services service;
OnWebResponseListener onWebResponseListener;
String url;
FormBody.Builder body;
Request request;
OkHttpClient client;
final static String TAG = "CallAddr";
public CallAddr(Map<String, String> data, CommonUtilities.services service, OnWebResponseListener onWebResponseListener, String url) {
this.service = service;
this.onWebResponseListener = onWebResponseListener;
this.url = url;
body = new FormBody.Builder();
for (String key : data.keySet()) {
body.add(key, data.get(key));
}
client = new OkHttpClient();
}
#Override
protected String doInBackground(String... strings) {
String result = "";
request = new Request.Builder().url(url).post(body.build()).build();
try {
Response response = client.newCall(request).execute();
result = response.body().string();
} catch (Exception e) {
Log.e(TAG,Log.getStackTraceString(e));
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (onWebResponseListener != null) {
onWebResponseListener.onWebResponse(service, s);
}
}
}
I want to parse the following JSON file but is starting with [ indicating to me that is an array, and then continues with { objects, my current parser is returning a JSON object.
My question is: how to modify the parser to parse this file? So that the parser will serve me for other JSON files, starting with objects or arrangements.
JSON FILE:
[{"codigo":1,"contenido":[{"codigo":1,"descripcion":"Lomo completo"},{"codigo":2,"descripcion":"Cerveza 1 Lt."}],"descripcion":"1 lomo completo y 1 cerveza de lt","precio":100.0},{"codigo":2,"contenido":[{"codigo":1,"descripcion":"Lomo completo"},{"codigo":2,"descripcion":"Cerveza 1 Lt."}],"descripcion":"2 lomo completo y 2 cerveza de lt","precio":190.0},{"codigo":3,"contenido":[{"codigo":1,"descripcion":"Lomo completo"},{"codigo":2,"descripcion":"Cerveza 1 Lt."}],"descripcion":"3 lomo completo y 3 cerveza de lt","precio":280.0},{"codigo":4,"contenido":[{"codigo":1,"descripcion":"Lomo completo"},{"codigo":2,"descripcion":"Cerveza 1 Lt."}],"descripcion":"4 lomo completo y 4 cerveza de lt","precio":370.0}]
JSON PARSER
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
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 JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Try to parser JSON FILE
public class OfertaService extends Service {
private static final String URL = "http://192.168.0.13:8080/ofertas/listado";
private static final String TAG_CODIGO = "codigo";
private static final String TAG_CONTENIDO = "contenido";
private static final String TAG_DESCRIPCION = "descripcion";
private static final String TAG_PRECIO = "precio";
private static final String TAG_CODIGO_PRODUCTO = "codigo";
private static final String TAG_DESCRIPCION_PRODUCTO = "descripcion";
#SuppressWarnings("rawtypes")
private List listaOfertas = new ArrayList();
public List getListaOfertas() {
return listaOfertas;
}
public void setListaOfertas(List listaOfertas) {
this.listaOfertas = listaOfertas;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#SuppressWarnings("unchecked")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
new DoInBack().execute();
} catch (Exception e) {
System.out.println("error en proceso de segundo plano DoInBack");
}
return 0;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
private class DoInBack extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
JSONParser jParser = new JSONParser();
JSONArray ofertasArray = null;
JSONArray productos = null;
JSONObject json = jParser.getJSONFromUrl(URL);
try {
String codigo = json.getString(TAG_CODIGO);
for (int i = 0; i < ofertasArray.length(); i++) {
JSONObject of;
of = ofertasArray.getJSONObject(i);
String id = of.getString(TAG_CODIGO);
// productos = json.getJSONArray(0);
List listaProductos = new ArrayList();
for (int j = 0; j < productos.length(); j++) {
JSONObject pro = productos.getJSONObject(j);
String idProducto = pro.getString(TAG_CODIGO_PRODUCTO);
String descProducto = pro
.getString(TAG_DESCRIPCION_PRODUCTO);
Hashtable<String, String> producto = new Hashtable<String, String>();
producto.put(TAG_CODIGO_PRODUCTO, idProducto);
producto.put(TAG_DESCRIPCION_PRODUCTO, descProducto);
listaProductos.add(producto);
}
String descripcionOferta = of.getString(TAG_DESCRIPCION);
String precio = of.getString("precio");
Hashtable ht = new Hashtable();
ht.put(TAG_CODIGO, id);
ht.put(TAG_CONTENIDO, listaProductos);
ht.put(TAG_DESCRIPCION, descripcionOferta);
ht.put(TAG_PRECIO, precio);
listaOfertas.add(ht);
}
System.out.println("parseo finalizado");
} catch (Exception e) {
}
return null;
}
}
I want to parse the following JSON file but is starting with [
indicating to me that is an array
When json string starting with [ means string is JSONArray
how to modify the parser to parse this file?
1. Convert json String to JSONArray instead of JSONObject:
JSONArray jsonArray = new JSONArray(json);
2. Change return type of getJSONFromUrl method to JSONArray from JSONObject
3. In doInBackground get response from getJSONFromUrl method in JSONArray:
JSONArray jsonArray = jParser.getJSONFromUrl(URL);
I have used httpclient to call a restapi written in django. It returned the json output. My httpresponse variable stored it and later convert the reponse to string and then to json object, i think its lengthy though it is working . I am really new to java , can anybody advise me , what is the best alternative logic to the code below
public void onClick(View v) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://10.0.2.2:8000/api/ca/entry/?
format=json&username=pragya");
try {
// Add your data
//List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
//nameValuePairs.add(new BasicNameValuePair("username", un.getText().toString()));
//nameValuePairs.add(new BasicNameValuePair("username", pw.getText().toString()));
//httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append((line + "\n"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
JSONObject jsonObject = new JSONObject(sb.toString());
JSONObject meta = jsonObject.getJSONObject("meta");
String limit = meta.getString("limit");
Toast.makeText(HelloWorldActivity.this, limit, Toast.LENGTH_SHORT).show();
JSONArray array = jsonObject.getJSONArray("objects");
String key = array.getJSONObject(0).getString("api_key");
String uname = array.getJSONObject(0).getString("username");
Toast.makeText(HelloWorldActivity.this, uname + " " + key,
Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Toast.makeText(HelloWorldActivity.this, sb.toString(), Toast.LENGTH_SHORT).show();
} catch (ClientProtocolException e) {
Toast.makeText(HelloWorldActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(HelloWorldActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
}
}
});
the json is as follows
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, "objects": [{"api_key": "c87391754b522d0c83b2c8b5e4c8cfd614559632deee70fdf1b48d470307e40e", "homeAddress": "kathmandu", "resource_uri": "/api/ca/entry/1/", "username": "sumit"}]}
Use Gson library from google, it is perfect for these kind of tasks.
All you need to do is define a new class that contains fields with the names of the keys in the json object and then use Gson to parse the Json string directly into the object or vice versa.
So for example:
Json looks like this: "limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1.
Java Class will be:
public class MyClass {
private int limit;
private int next;
private int offset;
private int previous;
private int total_count;
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getNext() {
return next;
}
public void setNext(int next) {
this.next = next;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getPrevious() {
return previous;
}
public void setPrevious(int previous) {
this.previous = previous;
}
public int getTotal_count() {
return total_count;
}
public void setTotal_count(int total_count) {
this.total_count = total_count;
}
}
And use Gson code like that:
Gson gson = new Gson(); // Or use new GsonBuilder().create();
MyClass myClass = gson.fromJson(json, MyClass.class); // deserializes json into MyClass
Please note that the name of the class fields have to match exactly the name of the keys in the json string.
Always perform lengthy non-UI task using AsyncTask. All the operations you described, fetching of json and parsing them, can be performed in AsyncTask. Write the entire code which you have currently written in onClick event and write it doInBackground() of an AsyncTask.
Check the following for more details:
http://developer.android.com/reference/android/os/AsyncTask.html
How do I get the data from my AsyncTask? My MainActivity is calling the DataCall.getJSON function that triggers the AsyncTask but I am not sure how to get the data back to the original Activity.
MainActivity with call to DataCall that should return a string and save it in state_data
String state_data = DataCall.getJSON(spinnerURL,spinnerContentType);
DataCall:
public class DataCall extends Activity {
private static final String TAG = "MyApp";
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
protected void onPostExecute(String result) {
//THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing)
}
}
public void getJSON(String myUrlString, String contentType) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString });
}
}
modify your AsyncTask as below:
public class GetData extends AsyncTask<String, Void, String>
{
DataDownloadListener dataDownloadListener;
public GetData()
{
//Constructor may be parametric
}
public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
this.dataDownloadListener = dataDownloadListener;
}
#Override
protected Object doInBackground(Object... param)
{
// do your task...
return null;
}
#Override
protected void onPostExecute(Object results)
{
if(results != null)
{
dataDownloadListener.dataDownloadedSuccessfully(results);
}
else
dataDownloadListener.dataDownloadFailed();
}
public static interface DataDownloadListener {
void dataDownloadedSuccessfully(Object data);
void dataDownloadFailed();
}
}
and use it in your Activity
GetData getdata = new GetData();
getdata.setDataDownloadListener(new DataDownloadListener()
{
#SuppressWarnings("unchecked")
#Override
public void dataDownloadedSuccessfully(Object data) {
// handler result
}
#Override
public void dataDownloadFailed() {
// handler failure (e.g network not available etc.)
}
});
getdata.execute("");
NOTE: For the people who are reading this.
Please consider this post for the best and perhaps right implementation.
The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.
public class URLWithParams {
public String url;
public List<NameValuePair> nameValuePairs;
public URLWithParams()
{
nameValuePairs = new ArrayList<NameValuePair>();
}
}
and then I send it to a JSONClient:
public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
private final static String TAG = "JSONClient";
ProgressDialog progressDialog ;
GetJSONListener getJSONListener;
public JSONClient(GetJSONListener listener){
this.getJSONListener = listener;
}
#Override
protected String doInBackground(URLWithParams... urls) {
return connect(urls[0].url, urls[0].nameValuePairs);
}
public static String connect(String url, List<NameValuePair> pairs)
{
HttpClient httpclient = new DefaultHttpClient();
if(url == null)
{
Log.d(TAG, "want to connect, but url is null");
}
else
{
Log.d(TAG, "starting connect with url " + url);
}
if(pairs == null)
{
Log.d(TAG, "want to connect, though pairs is null");
}
else
{
Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
for(NameValuePair dog : pairs)
{
Log.d(TAG, "example: " + dog.toString());
}
}
// Execute the request
HttpResponse response;
try {
// Prepare a request object
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
response = httpclient.execute(httpPost);
// Examine the response status
Log.i(TAG,response.getStatusLine().toString());
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
return json;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String json ) {
getJSONListener.onRemoteCallComplete(json);
}
public interface GetJSONListener {
public void onRemoteCallComplete(String jsonFromNet);
}
}
Then call it from my main class like this
public class BookCatalog implements GetJSONListener {
private final String TAG = this.getClass().getSimpleName();
private String catalog_url = "URL";
private void getCatalogFromServer() {
URLWithParams mURLWithParams = new URLWithParams();
mURLWithParams.url = catalog_url;
try {
JSONClient asyncPoster = new JSONClient(this);
asyncPoster.execute(mURLWithParams);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onRemoteCallComplete(String jsonBookCatalogList) {
Log.d(TAG, "received json catalog:");
Log.d(TAG, jsonBookCatalogList);
JSONObject bookCatalogResult;
try {
bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
JSONArray books = bookCatalogResult.getJSONArray("books");
if(books != null) {
ArrayList<String> newBookOrdering = new ArrayList<String>();
int num_books = books.length();
BookCatalogEntry temp;
DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
for(int book_id = 0; book_id < num_books; book_id++) {
JSONObject book = books.getJSONObject(book_id);
String title = book.getString("title");
int version = book.getInt("price");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Although i disagree creating a new activity for that simple task there is
startActivityForResult()
to get data from another activity.
Check this. You can store your data to the Intent's extras. But still if you have a large amount of data you better off write it to a file get the result from the other activity that is done downloading and then read the file.
Serialize it and then read it. The only way I'm aware of.
Some options:
a) Make your bean implement Serializable interface, you can then pass your bean through Intent.
b) Implement Application interface (you need to make an entry in manifest), Have setter\getter method in your Application class. You can set your bean in Application from AsyncTask and later retrieve from Activity.
Sorry for answering so late, i think by this time you might have solved this problem. when i was searching for something else, i came across your question. I'm pasting a link here which might of some help for others.