I am new to JSON and I was wondering how I would pull some info and put it into a JSON Object and then read some of the values. The json info looks like this,
{
"photos":{
"page":1,
"pages":1802,
"perpage":100,
"total":"180134",
"photo": [
{
"id":"8711964781",
"owner":"21156896#N07",
"secret":"3e24e45977",
"server":"8553",
"farm":9,
"title":"Old Harbor",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
{
"id":"8712680696",
"owner":"21156896#N07",
"secret":"fe82f8387b",
"server":"8122",
"farm":9,
"title":"Rockefeller Plaza",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
....
It photo array goes on for quite a while. How would I get the values of "isPublic"? "Secret" is a String because of the "" and isPublic is an integer or boolean? I basically have to put them into a URL link and download the image.
public class ReadString extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... FlickrString) {
try {
json = getValue();
return json.getString(FlickrString[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) {
// TODO Auto-generated method stub
tvTest.setText(result);
}
This works for all the strings. How would I get the farm, isfriend, isfamily, and ispublic converted to a string? I tried something else now to get the Int values, I made a whole new class for reading the ints. But it isnt getting the correct int value. I have it download the int and I convert it to a string and then I change a textview to the string of the int using String.valueOf(x); What am i doing wrong?
public class ReadInt extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... FlickrString) {
try {
json = getValue();
int x = json.getInt(FlickrString[0]);
String y = String.valueOf(x);
return y;
} 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
tvTest.setText(result);
}
}
Thanks!
JSONObject jobj = result.getJSONObject("photo");
jobj.getBoolean("ispublic");
jobj.getInt("isfriend");
The variable result is of typeJsonObject that should contain the entire object have pasted above in your code
Java is not like C++.In C++ 0 is false and other integers are true
I think you should create a function like this
private void boolean convertIntToBool(int value) {
if(value==0) {
return false;
} else {
return true;
}
}
and use it in the JSON parsing like this for example
boolean isfamily = convertIntToBool(jsonPhotoObject.getInt("isfamily"));
I guess you already know about the JSON parsing so I won't give so much example, but if you have another question about my answer feel free to ask in the comment :)
we assume the jsonString is your json result. You can get the your values like this:
protected String doInBackground(String... FlickrString) {
try {
JSONObject result = new JSONBOject(jsonString);
JSONObject photots = (JSONObject)result.get("photos");
JSONArray photosArray = (JSONArray) result.get("photo");
for(int i = 0; i < photosArray.length(); i++) {
JSONObject item = potosArray.get(i);
//ispublic
int ispublic = item.getInt("ispublic");
//isfriend
int isfriend = item.getInt("isfriend");
//isfamily
int isfamily = item.getInt("isfamily");
}
json = getValue();
return json.getString(FlickrString[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;
}
I would recommend that you try either Jackson or Gson and convert the JSON into some POJOs. I find that it's easier and less error prone to work with java objects instead of JSONObject, JSONArray and such. Here's an example of how it would work using Jackson. First we create the Objects that map to the JSON data:
public class Photos {
#JsonProperty
private int page;
#JsonProperty
private int pages;
...
#JsonProperty("photo")
public List<Photo> photoList;
}
public class Photo {
#JsonProperty
private String id;
#JsonProperty
private String owner;
...
#JsonProperty("ispublic")
public boolean isPublic;
#JsonProperty("isfriend")
public boolean isFriend;
#JsonProperty("isfamily")
public boolean isFamily;
}
Once we've created our pojos we can convert the JSON data into objects using the ObjectMapper. AT least when it comes to Jackson it automatically tries to convert integers to boolean (0 = false, anything else = true) and Strings to booleans ("true" and "false").
ObjectMapper mapper = new ObjectMapper();
Photos photos = mapper.readValue(json, Photos.class);
for(Photo photo : photos.photoList) {
if(photo.isPublic) {
// do something
}
}
PS I've made some of the properties of the pojos public to make the example shorter. You may wish to add getters and keep the properties private.
Related
i always found the answer to my Questions in StackoverFlow but not this time, so i'm trying to ask it, and i hope that you can help me, and Thanks even if you coudn't.
I'm trying to use the mysql query
Select * From `Table`
and returning a resultset from asynctask using .get() the problem is that after executing the query and getting the returned value when the asynctask tries to get back in the program he loop infinity,
PS:when i use other query like "Select * From Table Where something = other thing" it works perfectly.
here 2 methodes in my class DataBaseManager which got 2 params: Conn type connexion and member type ResultSet
/* asynctask pour la connexion*/public void Selmem(String ...a){
final class Select_member extends AsyncTask<String, Integer, ResultSet> {
#Override
protected ResultSet doInBackground(String... params) {
try {
ResultSet member2;
String myDriver = "com.mysql.jdbc.Driver";
Class.forName(myDriver).newInstance();
conn = DriverManager.getConnection(params[0], "root", "");
if(params.length==6)
member2=select_member(params[1],params[2],params[3],params[4],params[5]);
else
member2=select_member(params[1],params[2],params[3]);
conn.close();
return(member2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("printf","NOT SELECTED");
return null;
}
// TODO Auto-generated method stub
}
}
try {
if(a.length==6)
member=new Select_member().execute(a[0],a[1],a[2],a[3],a[4],a[5]).get();
else
member=new Select_member().execute(a[0],a[1],a[2],a[3]).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ResultSet select_member(String ...a){
String sql;
PreparedStatement prest;
try {
if(a.length==5)
{
sql="SELECT * FROM `"+a[0]+"` WHERE "+a[1]+" = '"+a[2]+"' and `"+a[3]+"` = '"+a[4]+"'";
prest= conn.prepareStatement(sql);
}
else if (a[2].equals(""))
{
sql="SELECT * FROM `"+a[0]+"`";
prest= conn.prepareStatement(sql);
}
else
{
sql="SELECT * FROM `"+a[0]+"` WHERE `"+a[1]+"` = '"+a[2]+"'";
prest= conn.prepareStatement(sql);
}
prest= conn.prepareStatement(sql);
ResultSet member1;
member1 = prest.executeQuery();
ResultSet member2=member1;
if(member1.next())
return member2;
else
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
this is where i Call my Class to try to Select from my database, ps: the program dosen't even get to my loop (so i don't think that my loop is the problem i used the debugger to see where is the problem)
public class Deniere_Op extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_deniere__op);
Intent activite=getIntent();
DataBaseManager base=new DataBaseManager();
String login=activite.getExtras().getString("login");
base.Selmem("jdbc:mysql://10.0.2.2:3306/db_app",login , "", "");
if(base.member==null)
{
Toast.makeText(getApplicationContext(), "Aucune Transaction",Toast.LENGTH_LONG).show();
}
else
{int i=0;
do{i++;
for(int j=1;j<=6;j++)
{String concat=new String();
concat=concat.valueOf(i)+concat.valueOf(j);
String message;
try {
message = base.member.getString(j);
String a="textview"+concat;
int resID=getResources().getIdentifier(a, "id",getPackageName());
TextView text=(TextView) findViewById(resID);
text.setText(message);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
base.member.next();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}while(base.member!=null);
}
}
I hope that this can make you understand my problem and helps you to help me :D :D.
the logcat hope it will help
I have an AsyncTask class which parse json data and inserts into an object, when I call it in normal activity classes it shows that data have been parsed but when I execute this on a class which extends Application then it gives zero result. Here is my class
public class AppGlobalData extends Application {
public ArrayList<YoutubeItem> gotItem= new ArrayList<YoutubeItem>();
private YouTubeParser parser;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
new ParserLoader().execute();
}
public class ParserLoader extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.i("Succeed?", "Yes");
parser = new YouTubeParser(
"http://powergroupbd.com/youtube/getyoutubejson.php");
try {
gotItem = parser.parseInitiator();
} 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;
}
}
public ArrayList<YoutubeItem> getGotItem() {
return gotItem;
}
public void setGotItem(ArrayList<YoutubeItem> gotItem) {
this.gotItem = gotItem;
}
}
I cant figure out the problem, can anyone help?
please be noted that this class runs and logs my String but doesnt parse data.
I think what might happen is that when new ParserLoader().execute(); it doing the work asynchronously. When your Activity load and call the getGotItem() the Asynctask might not have finished
I can't explain why onPostExecute is not being called in my code. I have successfully used almost this exact code with a different app before. It prints 'onPreExecute' and the successful result of the JSON fetch from doInBackground just before return result; but then onPostExecute doesn't print anything - with the super call or not - and moreover doesn't return my string to the UI thread. Any ideas?
public class PrivateLoadFromServer extends AsyncTask<String, Integer, String> {
InputStream is = null;
String result = null;
String error_text="";
JSONObject j = null;
String url;
SQLiteOpenHelper helper;
CustomActivity activity;
private Context context;
private ProgressDialog dialog;
private int count;
String employee;
String text;
public PrivateLoadFromServer(CustomActivity activity,String employee,String url){
this.url=url;
this.employee=employee;
this.activity=activity;
}
#Override
protected void onPreExecute() {
system.out.println("onPreExecute");
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
System.out.println("onPostExecute");
activity.setJSONResult(result);
/*
if(result!=null){
System.out.println("Task reported successful");
taskHandler.taskSuccessful(this.result);
activity.setJSONResult(this.result);
} else {
taskHandler.taskFailed();
}
*/
//return;
}
#Override
protected String doInBackground(String... params) {
System.out.println("Running aSyncTask");
// Successful code to get JSON result string from server omitted.
System.out.println("Raw at doInBackground: " + result);
return result;
EDIT: Should've posted this originally, I call it as an inner class in CustomActivity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
helper=new DBHelper(this);
loadBasicData();
}
private void loadBasicData() {
// If you can encode all of these into one JSON Object, cool.
String url="*****" //Omitted URL.
String employee=null;
PrivateLoadFromServer syncTask = new PrivateLoadFromServer(this,employee,url);
syncTask.execute();
try {
syncTask.get(15000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONResult at Activity:"+jsonResult); // jsonResult is null
}
}
public void setJSONResult(String result){
System.out.println("setJSONResult"+result);
this.jsonResult=result; // jsonResult is a field in the Activity.
}
Because you are calling get, the JSON result is also returned from this method (see the source code of AsyncTask.java. So you can call your method directly on the output.
try {
setJSONResult(syncTask.get(15000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
Check if your are explicitly cancelling AsyncTask somewhere in the code before it could postExecute.
onPostExecute() is called on the main UI thread. If its not getting called, it means your UI thread is blocked doing something else.
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.
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