After a few weeks of trying numerous examples found here and it seems throughout the web, I'm stumped. I can retrieve the desired search results from Google Shopping just fine:
{ "items": [ { "product": {
"title": "The Doctor's BrushPicks Toothpicks 250 Pack",
"brand": "The Doctor's" } } ] }
My problem is that I have the data sitting in a string, how do I extract the two values (title,brand) in order to use them elsewhere in the program?
Here is the class in question:
public class HttpExample extends Activity {
TextView httpStuff;
DefaultHttpClient client;
JSONObject json;
final static String URL = "https://www.googleapis.com/shopping/search...";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.httpex);
httpStuff = (TextView) findViewById(R.id.tvHttp);
client = new DefaultHttpClient();
new Read().execute("items");
}
public JSONObject products(String upc) throws ClientProtocolException, IOException, JSONException {
StringBuilder url = new StringBuilder(URL);
url.append(upc);
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONObject timeline = new JSONObject(data);
return timeline;
} else {
Toast.makeText(HttpExample.this, "error", Toast.LENGTH_SHORT);
return null;
}
}
public class Read extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
String upc = ExportMenuActivity.upc;
json = products(upc);
return json.getString(params[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result){
httpStuff.setText(result);
}
}
}
The output of httpStuff.setText(result):
[{"product":{"brand":"The Doctor's, "title":"The Doctor's..."}}]
A solution that'd work on all versions of Android would look something like this:
JSONObject products = products(jsonStr);
JSONArray itemArray = products.getJSONArray("items");
for(int i=0; i<itemArray.length(); i++) {
if(itemArray.isNull(i) == false) {
JSONObject item = itemArray.getJSONObject(i);
String title = item.getString("title");
String brand = item.getString("brand");
}
}
JsonReader is nice, but is only available in API 10 and up. So it might or might not work for you.
You should use a JsonReader for reading the json string. Its very easy and well documented with very good sample.. here
Related
I am trying to fetch some data from Web Server through JSON. I am using asynctask to do so. Normally it is taking 5-10 seconds to be shown in my ListView.
Hence I want to put spinner progress bar. My code is working fine only problem is the progress bar is not visible.
MyActivity code to call asyntask
try{
JSONObject output = new AsyncTaskJsonParse(this,status, A, B, city).execute().get();
try {
JSONObject output = new AsyncTaskJsonParse(ListViewDisplay.this,status, bgrp, antigen, city).execute().get();
JSONObject src = output.getJSONObject("data");
String flag = output.getString("success");
String flagmsg = output.getString("message");
if (flag == "1") {
JSONArray jarr_name = new JSONArray(src.getString("name"));
JSONArray jarr_fathername = new JSONArray(src.getString("fathername"));
JSONArray jarr_moh = new JSONArray(src.getString("moh"));
JSONArray jarr_city = new JSONArray(src.getString("city"));
JSONArray jarr_phone = new JSONArray(src.getString("phone"));
int n = jarr_name.length();
name_array = new String[n];
fathername_array = new String[n];
moh_array = new String[n];
phone_array = new String[n];
city_array = new String[n];
for (int i = 0; i < n; i++) {
name_array[i] = (String) jarr_name.get(i);
fathername_array[i] = (String) jarr_fathername.get(i);
moh_array[i] = (String) jarr_moh.get(i);
phone_array[i] = (String) jarr_phone.get(i);
city_array[i] = "Vadodara";
Log.d("Inside StringArray", i + "");
}
String msg = src.getString("name");
list = (ListView) findViewById(R.id.listView);
CustomListAdapter custAdaptor = new CustomListAdapter(this, name_array, fathername_array, mohalla_array, city_array, phone_array);
list.setAdapter(custAdaptor);
}else
{
Toast.makeText(this, "Data not found" + flagmsg, Toast.LENGTH_LONG).show();
}
}catch(ExecutionException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(InterruptedException e)
{
e.printStackTrace();
}catch(JSONException je)
{
}
Standalone asyntask with progressbar code
public class AsyncTaskJsonParse extends AsyncTask<String, String, JSONObject>
{
String A,B;
private String url = "abc.com/check.php";
List<NameValuePair> param=new ArrayList<NameValuePair>();
private Context context;
private ProgressDialog progress;
public AsyncTaskJsonParse(Context context,String A,String B,String antigen,String city)
{
this.A=A;
this.B=B;
this.city=city;
this.context=context;
progress=new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.e("In preexecution ", "Preexecution 1");
progress.setMessage("Processing...");
progress.setIndeterminate(true);
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setCancelable(true);
Log.e("In preexecution azam", "Preexecution 2");
progress.show();
if(progress.isShowing())
{
Log.d("In preexecution ", "Showing 2");
}
}
//rest of code i.e. doInBackground and postexecute come after this.
#Override
protected JSONObject doInBackground(String... arg0) {
// TODO Auto-generated method stub
try
{
JsonParsor parse=new JsonParsor();
Log.d("diInbackgrnd ","Dialog box");
jsonobj = parse.getJSONFromUrl(url, param);
}
catch(Exception e)
{
Log.e(TAG, " "+e );
}
return jsonobj;
}
#Override
protected void onPostExecute(JSONObject result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//pDialog.dismiss();
if(progress.isShowing())
{
Log.e("In onPost ", "Showing 2");
}
progress.dismiss();
}
}
In my log I can see the message "In preexecution Showing 2". And the appliaction is working as expected but the Spinner progressbar is not visible.
Note: I did not add any progressbar component in any xml file. Does i need to add it? if yes then where and how?
class JsonParser.java
public class JsonParsor {
final String TAG = "JsonParser.java";
static InputStream is = null;
static JSONObject jObj = null;
static String str = "";
public JSONObject getJSONFromUrl(String url,List<NameValuePair> params) {
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
post.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try
{
BufferedReader br=new BufferedReader(new InputStreamReader(is,"iso-8859-1"), 8);
StringBuilder builder=new StringBuilder();
String line=null;
while((line=br.readLine())!=null)
{
builder.append(line + "\n");
}
is.close();
str=builder.toString();
}
catch(Exception e)
{
}
try {
jObj=new JSONObject(str);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jObj;
}
}
I suspect your problem is that your AsyncTask finishes immediately as parse.getJSONFromUrl... is also Async. So whats happening is that progress.dismiss(); in onPostExecute invoked also immediately.
Try removing progress.dismiss(); from onPostExecute and see what happens
This should work. But without the progress.setMessage("Processing...");
You can still set that.
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(getActivity(),R.style.MyTheme);
dialog.setCancelable(false);
dialog.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
dialog.show();
}
I'm trying to retrieve data from mysql using asynctask. But I got this
" Type mismatch: cannot convert from AsyncTask
to String"
Though the return from the asynctask process is already string
Here's my codes
public void tampilkanPenyakit() {
try {
String nama = URLEncoder.encode(username, "utf-8");
urltampil += "?" + "&nama=" + nama;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
xResult = getRequestTampil(urltampil);
try {
parse();
} catch (Exception e) {
e.printStackTrace();
}
}
class ProsesTampil extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
String sret = "";
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(params[0]);
try{
HttpResponse response = client.execute(request);
sret = EditPenyakit.request(response);
}catch(Exception ex){
}
return sret;
// TODO Auto-generated method stub
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
public String getRequestTampil(String UrlTampil){
String sret="";
sret= new ProsesTampil().execute(UrlTampil);
return sret;
}
private void parse() throws Exception {
//jObject = new JSONObject(xResult);
jObject = new JSONObject(xResult);
String sret = "";
JSONArray menuitemArray = jObject.getJSONArray("food");
cb_menu1 = (CheckBox) findViewById(R.id.cb_menu1);
cb_menu2 = (CheckBox) findViewById(R.id.cb_menu2);
cb_menu3 = (CheckBox) findViewById(R.id.cb_menu3);
for (int i = 0; i < menuitemArray.length(); i++) {
sret =menuitemArray.getJSONObject(i).getString(
"penyakit").toString();
System.out.println(sret);
if (sret.equals("1")){
cb_menu1.setChecked(true);
}
else if (sret.equals("2")){
cb_menu2.setChecked(true);
}
}
}
Any help would be appreciated. thanks
The AsyncTask execute() method return the Asyntask itself, you cannot convert it to String.
You need to handle the result in the onPostExecute() method.
Other option could be use the AsynTask get method :
sret= new ProsesTampil().execute(UrlTampil).get();
Take in account the doc:
Waits if necessary for the computation to complete, and then retrieves its result.
After following a tutorial online I was able to retrieve some data from twitter for my android application. The following code works. I just basically want to build an application which can retrieve data such as Diablo 3 character level. How do I go about doing this? I think I have to use this URL to retrieve the data http://us.battle.net/api/d3/profile/Fauntleroy-1134/ however I am having no luck.
public class HttpExample extends Activity {
TextView httpStuff;
HttpClient client;
JSONObject json;
final static String URL = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.httpex);
httpStuff = (TextView) findViewById(R.id.tvHttp);
client = new DefaultHttpClient();
new Read().execute("created_at");
}
public JSONObject lastTweet(String username) throws ClientProtocolException, IOException, JSONException{
StringBuilder url = new StringBuilder(URL);
url.append(username);
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
if (status == 200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONArray timeline = new JSONArray(data);
JSONObject last = timeline.getJSONObject(0);
return last;
}else{
Toast.makeText(HttpExample.this, "error", Toast.LENGTH_SHORT);
return null;
}
}
public class Read extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try{
json = lastTweet("");
return json.getString(params[0]);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
httpStuff.setText(result);
}
}
}
The data your are retrieving from here are stored in an Array, so when you parse the data with
JSONArray timeline = new JSONArray(data);
you will get your JSONArray. Every element of the Array is an Object, so you get it with JSONObject last = timeline.getJSONObject(0); If you read the json string here you'll notice that the string starts with "{", so the root element is not an Array but an Object.
You need to change your parsing code, try something like this:
// test json string
String data = "{\"heroes\" : [ {\"name\" : \"UUUGUUUUUUUU\",\"id\" : 92352,\"level\" : 60,\"hardcore\" : false,\"paragonLevel\" : 0,\"gender\" : 0,\"dead\" : false,\"class\" : \"demon-hunter\",\"last-updated\" : 1340492305}, {\"name\" : \"RhubarbVole\",\"id\" : 7531555,\"level\" : 50,\"hardcore\" : false,\"paragonLevel\" : 0,\"gender\" : 1,\"dead\" : false,\"class\" : \"monk\",\"last-updated\" : 1339377909}, {\"name\" : \"VoodooFrodo\",\"id\" : 7698952,\"level\" : 32,\"hardcore\" : false,\"paragonLevel\" : 0,\"gender\" : 0,\"dead\" : false,\"class\" : \"witch-doctor\",\"last-updated\" : 1339376344}, {\"name\" : \"CheeseBird\",\"id\" : 13139301,\"level\" : 7,\"hardcore\" : false,\"paragonLevel\" : 0,\"gender\" : 1,\"dead\" : false,\"class\" : \"wizard\",\"last-updated\" : 1338098485} ]}";
root = new JSONObject(data);
JSONArray heroes = root.getJSONArray("heroes");
List<JSONObject> heroesList = new ArrayList<JSONObject>();
for(int i=0;i<heroes.length();i++){
JSONObject hero = heroes.getJSONObject(i);
heroesList.add(hero);
}
//...
JSONObject hero = heroesList.get(x);
int level = hero.getInt("level");
I would like to thank all the users in this community for helping me get as far as I am in my project today.
I now need your help once again. So far, I am able to establish a connection in my project from this JSON link (REMOVED FOR PRIVACY CONCERNS)
The problem is I am only able to parse one string, (firstName)
Here is my code:
public class JSONActivity extends Activity {
static TextView http;
HttpClient client;
JSONObject json;
final static String URL = "REMOVED FOR PRIVACY CONCERNS
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
http = (TextView) findViewById(R.id.http);
client = new DefaultHttpClient();
new Read().execute("firstName");
}
public JSONObject getpw(String password) throws ClientProtocolException,
IOException, JSONException {
StringBuilder url = new StringBuilder(URL);
url.append(password);
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONObject getname = new JSONObject(data);
return getname;
} else {
Toast.makeText(JSONActivity.this, "error", Toast.LENGTH_SHORT);
return null;
}
}
public class Read extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
json = getpw("trustme");
return json.getString("firstName");
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
http.setText(result);
}
}
}
My question is, how can I parse multiple strings rather than just "firstName"?
You can get it all by doing the following:
String firstname = json.getString("firstName");
String lastname = json.getString("lastName");
int checkedIn = json.getInt("checkedIn");
int updated = json.getInt("checkedindatetime");
JSONObject address = json.getJSONObject("address");
String streetaddress = address.getString("streetAddress");
String city = address.getString("city");
etc...
JSONArray phoneNumbers = json.getJSONArray("phoneNumber");
String type = phoneNumbers.getJSONObject(0).getString("type");
etc...
Hope this helps.
A good resource for looking at json, is this validator.
I have a class extending listFragment. I have written code for fetching json response in a method which is called in oncreate of the class. For fetching json in background I have created new inner class which extends asyncTask. I can get the jsonarrays and strings in the json response in the logcat. But when I try to save them in a string array and pass them my custom baseadapter, I get a nullpointer exception.
public class OnlineInfo extends ListFragment {
public static String result;
public String[] Technologies1;
public String[] TechnologyDescription1;
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
downloadjsonresponse();
}
public class Download extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
StringBuilder stringbuilder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet url = new HttpGet(params[0]);
try
{
Log.d("in background", "in background");
HttpResponse response = client.execute(url);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line ;
while((line = reader.readLine()) != null)
{
stringbuilder.append(line);
}
}
catch(ClientProtocolException e)
{
Log.d("error in clientprotocol", "error");
e.printStackTrace();
}
catch(IOException e)
{
Log.d("error in IO", "error");
e.printStackTrace();
}
return stringbuilder.toString();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
OnlineInfo.result = result;
try {
JSONObject jsonobject = new JSONObject(result);
JSONArray raja = jsonobject.getJSONArray("Technologies");
//String raja = jsonobject.getJSONArray("Technologies").getJSONObject(0).getString("desc");
//Log.d("desc:", raja);
for(int i=0; i<raja.length();i++)
{
Technologies1[i] = raja.getJSONObject(i).getString("name");
TechnologyDescription1[i] = raja.getJSONObject(i).getString("desc");
Log.d("technology :", raja.getJSONObject(i).getString("name"));
Log.d("technologydescription :", raja.getJSONObject(i).getString("desc"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("desc:", "error");
}
getListView().setAdapter(new AdapterForOnlineInfo(getActivity(), OnlineInfo.this.Technologies1, OnlineInfo.this.TechnologyDescription1));
}
}
public void downloadjsonresponse()
{
Download jsonresponse = new Download();
jsonresponse.execute("http://www.avantajsoftwares.com/result.json");
}
}
I could get the results in logcat whenever I comment these two lines in for-loop:
Technologies1[i] = raja.getJSONObject(i).getString("name");
TechnologyDescription1[i] = raja.getJSONObject(i).getString("desc");
Don't know what's going wrong. Please somebody provide me some insight....:-(
I think you need to allocate space in your string arrays to hold the new strings.
Just before your for loop, try putting something like this:
Technologies1 = new String[raja.length()];
TechnologyDescription1 = new String[raja.length()];