Reputation: 6234
this is my first post on Stackoverflow and I am trying to learn Android. I need to read a json file from within an android application.
I ran the following code on my phone and it doesn't display anything on my phone, I just get a blank screen.
I know there are ways to use Java libraries to parse json but that's is NOT what I am looking for. I would like to accomplish reading this json using ONLY tools provided by Android. Here's my json
I am using Android 4.0.3 Here's my json file data:
{
"offers": [
{
"id": "1",
"type":"xyz",
"description":"blah blah",
"url":"http://www.example.com/"
},
{
"id": "1",
"type":"xyz",
"description":"some description",
"url":"http://www.example.com/"
},
{
"id": "1",
"type":"xyz",
"description":"some description",
"url":"http://www.example.com/"
}
]
}
Here's my MainActivity.java
package com.pega.parsejson;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView jsonWrapper;
HttpClient httpClient;
JSONObject json;
final static String offersUrl="http://somewebsite.com/offers.json";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jsonWrapper=(TextView) findViewById(R.id.jsonWrap);
httpClient=new DefaultHttpClient();
new Read().execute("description");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public JSONObject jsonOffers() throws ClientProtocolException, IOException, JSONException {
//StringBuilder url=new StringBuilder(offersUrl);
HttpGet get=new HttpGet(offersUrl);
HttpResponse res=httpClient.execute(get);
int status=res.getStatusLine().getStatusCode();
if(status==200){
HttpEntity e=res.getEntity();
String data=EntityUtils.toString(e);
JSONArray timeline=new JSONArray("offers");
JSONObject jsonOffer=timeline.getJSONObject(0); //returns most recent offer
return jsonOffer;
}else{
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
return null;
}
}
public class Read extends AsyncTask<String, Integer, String>{
@Override
protected String doInBackground(String... params) {
try {
json=jsonOffers();
return (String) json.get("description"); //returns string w/ parameter passed in as "description"
} 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) {
jsonWrapper.setText(result);
}
}
}
I am also using the INTERNET PERMISSIONS:
Here's my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pega.parsejson"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.pega.parsejson.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And here's my textview right below:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/jsonWrap"
android:layout_width="match_parent"
android:layout_height="400dp"
android:text="" />
</RelativeLayout>
And here's my logcat:
[2013-08-07 23:35:41 - parseJson] ------------------------------
[2013-08-07 23:35:41 - parseJson] Android Launch!
[2013-08-07 23:35:41 - parseJson] adb is running normally.
[2013-08-07 23:35:41 - parseJson] Performing com.pega.parsejson.MainActivity activity launch
[2013-08-07 23:35:42 - parseJson] Uploading parseJson.apk onto device 'HT25EHX00690'
[2013-08-07 23:35:42 - parseJson] Installing parseJson.apk...
[2013-08-07 23:35:45 - parseJson] Success!
[2013-08-07 23:35:45 - parseJson] Starting activity com.pega.parsejson.MainActivity on device HT25EHX00690
[2013-08-07 23:35:46 - parseJson] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.pega.parsejson/.MainActivity }
Please note I do NOT want to use any json libraries to parse my json, I strictly would like to use ONLY android to parse the json. I just don't get why my mainActivity.java doesn't display anything on phone.
Apologize for the length of my post, really need help on this for a time sensitive project and YES, I have already read other similar questions on Stackoverflow and none seem to answer this question.
Could anybody please help me on this?
Thanks
Upvotes: 0
Views: 1344
Reputation: 3130
Try something like this:
if(status==200){
HttpEntity e=res.getEntity();
String data=EntityUtils.toString(e);
JSONObject jObj;
JSONArray data = null;
JSONObject jsonOffer;
jObj = new JSONObject(data);
data = jObj.getJSONArray("offers");
jsonOffer=data.getJSONObject(0);
return jsonOffer;
}
get values like
String id = jsonOffer.getString("id");
we have created json Object for your json. then we have got the array which is under "Offers" key. so we have data as an array. then we have got the first object of array in jsonoffer object. so we have data in jsonoffer and we can retrieve value by getString(keyName).
Hope it Helps!!
Upvotes: 1
Reputation: 8302
I believe your error lies in the code:
HttpEntity e=res.getEntity();
String data=EntityUtils.toString(e);
JSONArray timeline=new JSONArray("offers");
JSONObject jsonOffer=timeline.getJSONObject(0); //returns most recent offer
return jsonOffer;
The reason is that you are creating a NEW JSONArray instead of using the array from the JSON you receive.
Instead, you should parse the JSON you receive, using the built-in JSONObject and then select the array. Assuming data
holds the JSON text, you could do something like:
JSONObject json = new JSONObject(data);
JSONArray timeline = json.getJSONArray("offers");
return timeline.getJSONObject(0); // return most recent offer
Upvotes: 0
Reputation: 8251
Do something like the following,
public class Read extends AsyncTask<String, Integer, JSONObject>{
@Override
protected JSONObjectdoInBackground(String... params) {
try {
json=jsonOffers();
return json;
} 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(JSONObject result) {
try {
JSONArray offers=result.getJSONArray("offers");
for(int i=0;i<offers.length();i++)
{
JSONObject obj1=offers.getJSONObject(0);
String desc1=obj1.getString("description");
JSONObject obj2=offers.getJSONObject(1);
String desc2=obj2.getString("description");
JSONObject obj3=offers.getJSONObject(2);
String desc3=obj3.getString("description");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Now String
desc1,desc2,desc3 contains your 3 descriptions respectively. Do what ever you want with that string
.
Upvotes: 0