Running javascript in an android app? - java

There's a website which provides some javascript which emits information I need, is there a way through androids APIs, to use this javascript to emit whatever information it has and parse through it?
This is the javascript:
<script type="text/javascript" src="http://pulllist.comixology.com/js/pulllist/5b467b28e73595311e02fe32c3081e4a.js?date=2013-05-15"></script>
If you run it in a html file you'll notice it displays images and text it retrieves from a website, I'd like to get all that information in an android app.

I don't know if you can directly run javascript code, but you can run it within a webview (maybe a hidden one?) and intercept javascript calls with a javascript interface, in combination with injection into the webview I think you should be able to do almost everything you want.
If you'd need it, you could also download the js source, parse it as you wish and then feed it to the webview. If you want more info let me know ^^
the web is full of example anyway, here an example and another one
EDIT
ok you don't need to actually run that javascript, parsing it is enough, here a working example in android implementing #T.S. parsing method, to run it you just need to add android.permission.INTERNET to your manifest file and having a textview with myTextView id set.
public class MainActivity extends Activity implements Runnable{
TextView myTextView;
public Handler handler = new Handler(){
#Override
public void handleMessage(Message msg){
String source = (String)msg.obj;
// The index of the item
int i = 0;
// We search the data-string from the start
int position1 = 0;
// While there are items found, continue
while(true) {
// Look for the pattern a[index]={json data};
String lookFor1 = "a[" + String.valueOf(i) + "]={";
String lookFor2 = "};";
position1 = source.indexOf(lookFor1, position1+1);
// Check if we have a match
if(position1 > -1) {
// Find the end of the match
int position2 = source.indexOf(lookFor2, position1);
// Get the result
String result = source.substring(position1 + lookFor1.length() - 1, position2 + 1);
// Increase the index an check if we can find a next item
i++;
// Print out this row, which is a JSON representation of the data you want
Log.e("res",result);
try {
JSONObject obj = new JSONObject(result);
String title = obj.getString("title");
String img = obj.getString("img");
String src = new JSONObject(img).getString("src");
myTextView.append("\ntitle: "+title+"\nimgurl: "+src+"\n");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
// We haven't found a match, break out of while loop
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView = (TextView) findViewById(R.id.myTextView);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
String data = retrieve_data();
Message msg = handler.obtainMessage();
msg.obj = data;
handler.sendMessage(msg);
}
private String retrieve_data(){
String data = "";
String url = "http://pulllist.comixology.com/js/pulllist/5b467b28e73595311e02fe32c3081e4a.js?date=2013-05-15";
HttpClient httpclient = new DefaultHttpClient();
HttpGet request;
try {
request = new HttpGet(new URI(url));
request.addHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0");
HttpResponse response = httpclient.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
data = out.toString();
}
} catch (URISyntaxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
}

If it's just for displaying you could use the WebView with some custom styling.
Link: http://developer.android.com/reference/android/webkit/WebView.html
String html = "<script type='text/javascript' src='http://pulllist.comixology.com/js/pulllist/5b467b28e73595311e02fe32c3081e4a.js?date=2013-05-15'></script>";
String mime = "text/html";
String encoding = "utf-8";
WebView myWebView = (WebView)this.findViewById(R.id.myWebView);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadDataWithBaseURL(null, html, mime, encoding, null);
Update
I wrote a quick and dirty example of how you can extract the data from that javascript file:
import java.util.*;
import java.lang.*;
import java.net.*;
import java.io.*;
public class JavascriptToUsableData {
// Method to get a string from an URL
// Thanks to http://stackoverflow.com/a/4328733/1226267
public static String getText(String url) throws Exception {
URL website = new URL(url);
URLConnection connection = website.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
StringBuilder response = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
response.append(inputLine);
in.close();
return response.toString();
}
public static void main (String args[]) throws Exception {
// Get the data
String source = JavascriptToUsableData.getText("http://pulllist.comixology.com/js/pulllist/5b467b28e73595311e02fe32c3081e4a.js?date=2013-05-15");
// The index of the item
int i = 0;
// We search the data-string from the start
int position1 = 0;
// While there are items found, continue
while(true) {
// Look for the pattern a[index]={json data};
String lookFor1 = "a[" + String.valueOf(i) + "]={";
String lookFor2 = "};";
position1 = source.indexOf(lookFor1, position1+1);
// Check if we have a match
if(position1 > -1) {
// Find the end of the match
int position2 = source.indexOf(lookFor2, position1);
// Get the result
String result = source.substring(position1 + lookFor1.length() - 1, position2 + 1);
// Increase the index an check if we can find a next item
i++;
// Print out this row, which is a JSON representation of the data you want
System.out.println(result);
// I'm not in an Android environment right now, but there is a JSON reader you can use in Android
// I think it works somthing like this:
// resultObj = new JSONObject(result);
// And then access the data like this:
// resultObj.getString("title");
// resultObj.getString("guid");
// resultObj.getString("img");
// etc
} else {
// We haven't found a match, break out of while loop
break;
}
}
}
}
It can be optimized a lot and probably isn't fail-safe in it's current state, but it might give you some hints on how to start.

Related

Get Json data from the Url below(Url returns json data)

This is the URL which returns me the json object Link.
Now I need to get the json data to my code. When I try to access the link I get the html script. How do I get the json data from the above URL to my code. Here is my code.
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_select1 = "http://andpermission.byethost5.com/PermissionList.php";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select1);
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());
//Toast.makeText(MainActivity.this, "Please Try Again", Toast.LENGTH_LONG).show();
}
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) {
// TODO: handle exception
Log.e("log_tag", "Error converting result "+e.toString());
}
return null;
}
protected void onPostExecute(Void v) {
// ambil data dari Json database
try {
JSONArray Jarray = new JSONArray(result);
for(int i=0;i<Jarray.length();i++)
{
JSONObject Jasonobject = null;
//text_1 = (TextView)findViewById(R.id.txt1);
Jasonobject = Jarray.getJSONObject(i);
//get an output on the screen
//String id = Jasonobject.getString("id");
String name = Jasonobject.getString("name");
String db_detail="";
if(et.getText().toString().equalsIgnoreCase(name)) {
db_detail = Jasonobject.getString("detail");
text.setText(db_detail);
break;
}
//text_1.append(id+"\t\t"+name+"\t\t"+password+"\t\t"+"\n");
}
this.progressDialog.dismiss();
} catch (Exception e) {
// TODO: handle exception
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
}
Using string builder I append the content and I find only the java script and I don't find the json data. How to I get the json data from the above URL.
In string "Result" in my code I get the below output.
<html>
<body>
<script type="text/javascript" src="/aes.js"></script>
<script>
function toNumbers(d) {
var e = [];
d.replace(/(..)/g, function(d) {
e.push(parseInt(d, 16))
});
return e
}
function toHex() {
for (var d = [], d = 1 == arguments.length && arguments[0].constructor == Array ? arguments[0] : arguments, e = "", f = 0; f < d.length; f++) e += (16 > d[f] ? "0" : "") + d[f].toString(16);
return e.toLowerCase()
}
var a = toNumbers("f655ba9d09a112d4968c63579db590b4"),
b = toNumbers("98344c2eee86c3994890592585b49f80"),
c = toNumbers("b8eeb5e790c4a5395d01cde6b8230fdd");
document.cookie = "__test=" + toHex(slowAES.decrypt(c, 2, a, b)) + "; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/";
location.href = "http://andpermission.byethost5.com/PermissionList.php?ckattempt=1";
</script>
<noscript>This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support</noscript>
How do I get only the json data from the URL instead the java script.
Try the full URL: http://andpermission.byethost5.com/PermissionList.php?ckattempt=1.
And also make sure you are using GET instead of POST, because that's what the URL refers to.
Here a good example: http://www.learn2crack.com/2013/10/android-json-parsing-url-example.html
On the other hand, there are some libraries like Aquery, Okhttp and Volley, that do this job very good.

Can't download html source from a web page

im having problems downloading html source from a web page in android. I run the http client in a different thread and it is able to get the html text ( i logged the result) but later when i try to work with the downloaded html text the variable seems to be empty from the main thread. I assume the problem is rising because im unable to synchronize threads but i don't know how to fix it for now. When i debug the code, the global variable contains data in the run function but when i join threads and look after the join method the variable is empty. Here is my code (class which i run in a different thread)
public class LutrijaHr {
public String url;
public String savedHtml;
public LutrijaHr(String s){
this.url = s;
savedHtml = "";
}
public String donwloadSource(String passedUrl) throws Exception{
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(passedUrl);
HttpResponse response = client.execute(request);
String html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
str.append(line);
}
in.close();
html = str.toString();
savedHtml += html;
return html;
}
}
Parts of code from the main class:
String test = "";
LutrijaHr lhr = new LutrijaHr("https://www.lutrija.hr");
#Override
public void run() {
try {
test = lhr.donwloadSource(lhr.url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lhr.savedHtml = test;
Log.d("test", test);
}
Here is the part where i try to join the threads but the variable is empty
if (v.getId() == R.id.checkNumber){
Thread t = new Thread(new LotoMain(), "Page thread");
t.start();
try {
t.join();
etCheckedNumber.setText(lhr.savedHtml);
String smrki = test;
Log.d("testdsadasd", lhr.savedHtml);
Log.d("BOZO BOZO" ,test) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d("BOZO BOZO BOZO" ,test) ;
e.printStackTrace();
}
}
I would like to solve this problem without using the android asynctask class because i want to learn a bit about threads and how they operate.
Use "Lock"
Add this code to main class:
public Lock workingLock = new ReentrantLock();
String test = "";
LutrijaHr lhr = new LutrijaHr("https://www.lutrija.hr");
#Override
public void run() {
try {
workingLock.lock();
test = lhr.donwloadSource(lhr.url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lhr.savedHtml = test;
workingLock.unlock;
Log.d("test", test);
}
Now use it in:
if (v.getId() == R.id.checkNumber){
Thread t = new Thread(new LotoMain(), "Page thread");
try {
try {
workingLock.lock();
} catch (Exception e) {
e.printStackTrace();
}
etCheckedNumber.setText(lhr.savedHtml);
String smrki = test;
Log.d("testdsadasd", lhr.savedHtml);
Log.d("BOZO BOZO" ,test) ;
workingLock.unlock();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d("BOZO BOZO BOZO" ,test) ;
e.printStackTrace();
}
}
Try this, it will return the source of a given page as one long string which you can then manipulate however you need, and as its a standalone class/method you can call it on the UI thread or asyc or however you choose to.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class WebPage {
public static String getWebSource(String Url) throws IOException {
URL url = new URL(Url);
URLConnection urlConnection = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "UTF-8"));
String inputLine;
StringBuilder sb = new StringBuilder();
while ((inputLine = br.readLine()) != null)
sb.append(inputLine);
br.close();
return sb.toString();
}
}
Edit: If you want to call it from the UI thread, android won't by default let you do that. you will need to change the apps thread policy which can by done by running this when the app starts (Required a min API of 9)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
I "solved" the problem with declaring
String test = "";
as
static String test = "";
Even if this soultion works i don't understand why it wouldn't work with my original solution. If someone could light up this for me it would be really helpfull

Perform AsyncTask on Android / Posting JSON

I am working on an android app, and am running into some troubles with registering users. I want to post a JSON object to my server and receive one back. I can successfully create a JSON object with the right information but when I go to post it I get a NetworkOnMainThreadException or my HttpClient class returns null when it should be returning a JSONObject and I am very confident that my web server works correctly. I understand that you cannot connect to the network on the main thread and have created an HttpClient class that uses AsnycTask (although probably not correctly). I have been working on this for quite a while and would appreciate any guidance in the right direction.
//Main activity
#Override
public void onClick(View arg0) {
if(!(isEmpty(name) || isEmpty(username) || isEmpty(password) || isEmpty(email))) {
user = new JSONObject();
try {
user.put("username", username.getText().toString());
user.put("name", name.getText().toString());
user.put("email", email.getText().toString());
user.put("password", password.getText().toString());
} catch (JSONException e) {
e.printStackTrace();
}
jRegister = new JSONObject();
try {
jRegister.put("apiToken", Utilities.apiToken);
jRegister.put("user", user);
Log.i("MainActivity", jRegister.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
//
HttpClient client = new HttpClient(url, jRegister);
result = client.getJSONFromUrl();
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}else {
tv.setText("");
}
}
HttpClient Class
public class HttpClient extends AsyncTask<Void, Void, JSONObject>{
private final String TAG = "HttpClient";
private String URL;
private JSONObject jsonObjSend;
private JSONObject result = null;
public HttpClient(String URL, JSONObject jsonObjSend) {
this.URL = URL;
this.jsonObjSend = jsonObjSend;
}
public JSONObject getJSONFromUrl() {
this.execute();
return result;
}
#Override
protected JSONObject doInBackground(Void... params) {
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
StringEntity se;
se = new StringEntity(jsonObjSend.toString());
// Set HTTP parameters
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
// convert content stream to a String
String resultString= convertStreamToString(instream);
instream.close();
resultString = resultString.substring(1,resultString.length()-1); // remove wrapping "[" and "]"
JSONObject jsonObjRecv = new JSONObject(resultString);
// Raw DEBUG output of our received JSON object:
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
return jsonObjRecv;
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(JSONObject jObject) {
result = jObject;
}
private static String convertStreamToString(InputStream is) {
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();
}
}
return sb.toString();
}
}
I understand that you cannot connect to the network on the main thread
and have created an HttpClient class that uses AsnycTask (although
probably not correctly).
You are right you have not implemented it the right way.
In your onClick events (still on Main thread) you performed a network activity causing the error:
HttpClient client = new HttpClient(url, jRegister);
result = client.getJSONFromUrl();
Instead you should run the network operation inside of the AsnycTask
public class GetJsonTask extends AsyncTask<Void, Void, JSONObject >{
private String URL;
private JSONObject jsonObjSend;
public GetJsonTask(String URL, JSONObject jsonObjSend) {
this.URL = URL;
this.jsonObjSend = jsonObjSend;
}
#Override
protected JSONObject doInBackground(Void... params) {
JSONObject jsonObjRecv;
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
StringEntity se;
se = new StringEntity(jsonObjSend.toString());
// Set HTTP parameters
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
// convert content stream to a String
String resultString= convertStreamToString(instream);
instream.close();
resultString = resultString.substring(1,resultString.length()-1); // remove wrapping "[" and "]"
jsonObjRecv = new JSONObject(resultString);
// Raw DEBUG output of our received JSON object:
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
}
}
catch (Exception e) {
e.printStackTrace();
}
return jsonObjRecv;
}
protected void onPostExecute(JSONObject result) {
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}else {
tv.setText("");
}
}
}
Then you call your async in onclik method like this:
public void onClick(View arg0) {
//.......
GetJsonTask client = new GetJsonTask(url, jRegister);
client.execute();
}
One problem in your code is that your expectations of AsyncTask aren't quite right. In particular this function:
public JSONObject getJSONFromUrl() {
this.execute();
return result;
}
AsyncTask runs the code in the doInBackground() function in a separate thread. This means that once you call execute() you have two parallel lines of execution. You end up with what's called a Race Condition. When you reach the return result line, a couple of things can be happening:
doInBackground() hasn't run and therefore result is still has the default value. In this case null.
doInBackground() can be in the middle of the code. In your particular case because it doesn't modify result then this doesn't affect you much. But it could be on any line (or middle of a line sometimes if operations aren't atomic) when that return happens.
doInBackground() could've finished, but since onPostExecute() runs on the UI thread it has to wait until your onClick handler is finished. By the time onPostExecute() has a chance to run onClick already tried to update tv with whatever it was that getJSONFromUrl returned, most likely null.
The way to set up tasks with AsyncTask is to give it the information it needs to do it's work, start it up with execute, and since you can't know how long it will take to complete, let it handle the finishing steps of the task.
This means that after calling execute you don't wait around for it's result to update views (like in your case), but rather rely on the AsyncTask's onPostExecute or related methods to take over the next steps.
For your case this would mean that your onPostExecute should look something like:
protected void onPostExecute(JSONObject result) {
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}

How to download JSON data in android

I am developing an android application in which first I am sending request to Web service and getting the response status in 0 or 1 format if I get the response as 1 then complete JSON file is loaded.
My question is I want to make an offline app for which I want to download the JSON data from one activity and read that data in different activity with listview displaying title of every downloaded JSON file. After clicking the listview item, JSON data is displayed. And some of the JSON data items contains URL of images I also want to download them and display them in another activity.
I also want to encrypt the downloaded JSON data. Please Help me.
For reference I have attached the JSON file format.
{"test_time":7200,"time_taken":"0","time_left":"7200","score":null,"easy_score":null,"medium_score":null,"hard_score":null,"status":"n","sections":[{"section_id":"196498","section_name":"Reasoning Aptitude","section_no":1,"total_questions":"40","total_minutes":"24","questions":[{"question_id":"61562","question":{"1":{"text":"In a certain code GRANT is written as UOBSH and PRIDE is written as FEJSQ. How is SOLD written in that code?","image":"","imgHeight":"","imgWidth":""}},"correct_ans":{"1":{"text":"EMPT","image":"","imgHeight":"","imgWidth":""}},"rightOption":[],"rightOptionID":"246408","rightOptionNo":"2","anwer_explaination":{"1":{"text":"","image":"http://abc.com/testengine/images/questions/bankpower/image1.Jpeg","imgHeight":304,"imgWidth":212},"2":{"text":" ","image":"","imgHeight":"","imgWidth":""}},"question_time_taken":"10","marked":"0","skipped":"0","answer_id":"1395795","option_choose":"246407","question_status":1,"options":[{"OptionId":"246406","OptionDesc":{"1":{"text":"EPMT","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246407","OptionDesc":{"1":{"text":"TPME","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246408","OptionDesc":{"1":{"text":"EMPT","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246409","OptionDesc":{"1":{"text":"CKNR","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246410","OptionDesc":{"1":{"text":"ETPM","image":"","imgHeight":"","imgWidth":""}}}]},{"question_id":"61563","question":{"1":{"text":"Four of the following five are alike in a certain way and so form a group. Which is the one that does not belong to that group?","image":"","imgHeight":"","imgWidth":""}},"correct_ans":{"1":{"text":"27","image":"","imgHeight":"","imgWidth":""}},"rightOption":[],"rightOptionID":"246414","rightOptionNo":"3","anwer_explaination":{"1":{"text":"Mouse is odd rest are use for storage.","image":"","imgHeight":"","imgWidth":""}},"question_time_taken":"0","marked":"0","skipped":"1","answer_id":"","option_choose":"","question_status":3,"options":[{"OptionId":"246411","OptionDesc":{"1":{"text":"19","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246412","OptionDesc":{"1":{"text":"17","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246413","OptionDesc":{"1":{"text":"13","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246414","OptionDesc":{"1":{"text":"27","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246415","OptionDesc":{"1":{"text":"37","image":"","imgHeight":"","imgWidth":""}}}]}
parse all the data using the parser detailed in that link
http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
then Write all the data into a file using the method below , this way ur data is downloaded and saved as a file
public void appendData(String text)
{
File myFile = new File("sdcard/myfile.file");
if (!myFile.exists())
{
try
{
myFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(myFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You need to do something like this:
private class PrepareMapTask extends AsyncTask<String, Integer, Boolean>
{
// Initialize with invalid value
private int mPrepareResult = -1;
private String mJsonString = null;
protected Boolean doInBackground(String... urls)
{
mJsonString = downloadFileFromInternet(urls[0]);
if(mJsonString == null /*|| mJsonString.isEmpty()*/)
return false;
JSONObject jObject = null;
try {
jObject = new JSONObject(mJsonString);
JSONArray jsonImageArray = jObject.getJSONArray("imageTarget");
JSONArray jsonUrlArray = jObject.getJSONArray("videoUrls");
JSONArray jsonVideoOrUrlArray = jObject.getJSONArray("videoOrUrl");
if (jsonImageArray == null || jsonUrlArray == null)
return false;
for (int i = 0; i<jsonImageArray.length(); i++){
mapTargetUrl.put(jsonImageArray.get(i).toString(), jsonUrlArray.get(i).toString());
mVideoOrUrl.add(jsonVideoOrUrlArray.get(i).toString());
}
} catch (JSONException e) {
e.printStackTrace();
return false;
}
return true;
}
protected void onPostExecute(Boolean result)
{
}
private String downloadFileFromInternet(String url)
{
if(url == null /*|| url.isEmpty() == true*/)
new IllegalArgumentException("url is empty/null");
StringBuilder sb = new StringBuilder();
InputStream inStream = null;
try
{
url = urlEncode(url);
URL link = new URL(url);
inStream = link.openStream();
int i;
int total = 0;
byte[] buffer = new byte[8 * 1024];
while((i=inStream.read(buffer)) != -1)
{
if(total >= (1024 * 1024))
{
return "";
}
total += i;
sb.append(new String(buffer,0,i));
}
}catch(Exception e )
{
e.printStackTrace();
return null;
}catch(OutOfMemoryError e)
{
e.printStackTrace();
return null;
}
return sb.toString();
}
private String urlEncode(String url)
{
if(url == null /*|| url.isEmpty() == true*/)
return null;
url = url.replace("[","");
url = url.replace("]","");
url = url.replaceAll(" ","%20");
return url;
}
}
Take the data structures as per your json and modify the code.
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
// Set HTTP parameters
/*StringEntity se;
se = new StringEntity(jsonObjSend.toString());*/
jsonObjSend.length();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(jsonObjSend.length());
nameValuePairs.add(new BasicNameValuePair("data", jsonObjSend.toString()));
// Log.i("jsonObjSend.toString()","jsonObjSend.toString()"+jsonObjSend.toString());
Log.i("HTTPPOST","URL: "+URL);
Log.i("HTTPPOST","Request: "+jsonObjSend.toString());
UrlEncodedFormEntity en=new UrlEncodedFormEntity(nameValuePairs);
en.getContent();
httpPostRequest.getParams().setParameter("http.socket.timeout", new Integer(600000));
httpPostRequest.setEntity(en);
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
Log.i(TAG, httpPostRequest.getRequestLine().getProtocolVersion().toString());
responses = convertEntityToString(response.getEntity(), "UTF-8");
Log.i("HTTPPOST","Responce: "+responses);
Log.i("HTTPPOST","******************");
//Log.i("Encoding",response.getEntity().getContentEncoding().getName());
if (response.equalsIgnoreCase("")) {
webresponse = 1;
} else {
webresponse = 0;
}
} catch (IOException e) {
h.post(new Runnable() {
#Override
public void run() {
pd.dismiss();
AlertNullWebserviceResponce();
}
});
e.printStackTrace();
}

Empty JSON response when trying to parse JSONObject with one JSONArray

I got code that gets JSONArrays, but however when I try to get JSONObject that contains only one JSONArray it gives me empty JSONArray.
For example if I need to get data from this JSONObject:
{"events":[{"start":1357714800,"end":1357736400,"name":"Example1","description":""}]}
I get {"events":[]} as JSONObject, [] meaning that it doesn't contain any JSONArrays. Also length of JSONObject is in this case 0. But it doesn't throw any kind of Exceptions.
but if JSONObject contains multiple JSONArrays like this:
{"events":[{"start":1357714800,"end":1357736400,"name":"Example1","description":""},{"start":1357714600,"end":1357736500,"name":"Example2","description":""},{"start":1357514800,"end":1357536400,"name":"Example3","description":""}]}
then my code works perfect.
Here is the code I use to parse JSON:
private void getObjects(String url) throws JSONException, Exception {
JSONObject jsonObject = new JSONObject(new NetTask().execute(url).get());
JSONArray job1 = jsonObject.getJSONArray("events");
System.out.println(jsonObject.toString());
System.out.println("JOB1 LENGTH: "+job1.length());
for (int i = 0; i < job1.length(); i++) {
JSONObject jsonEvent = job1.getJSONObject(i);
int start = jsonEvent.getInt("start");
int end = jsonEvent.getInt("end");
String name = jsonEvent.getString("name");
String description = jsonEvent.getString("description");
}
}
public class NetTask extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... params)
{
String jsonText = "";
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1) {
buffer.append(chars, 0, read);
}
jsonText = buffer.toString();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return jsonText;
}
}
is there something wrong that I am missing or is this normal behaviour?
I tried your given code (though I just made the AsyncTask just return the single-array string, and had to replace the opptunti.getString() stuff with jsonEvent.getString()). It worked fine, aside from the fact that you're probably blocking the UI thread to wait for the server response.
My guess is the problem is that you are hitting the wrong URL, that the parameters are wrong or something like that.

Categories