How I can parse JSON result from URL request? - android

I am a newbie in android and java. I want to get a url request (result is JSON) and parsing it (for example get JSON weather from yahoo api's).
I copy getStringFromUrl Function and I know error for my function (setWeather). please help me.
public static String getStringFromURL(String urlString) throws IOException {
HttpURLConnection urlConnection;
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
char[] buffer = new char[1024];
String outputString;
StringBuilder builder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line).append("\n");
}
bufferedReader.close();
outputString = builder.toString();
return outputString;
}
public void setWeather (View view) throws IOException, JSONException {
String json = getStringFromURL("https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='Esfahan')&format=json");
JSONObject jso = new JSONObject(json);
JSONObject query = jso.getJSONObject("query");
JSONObject result = query.getJSONObject("results");
JSONObject channel = result.getJSONObject("channel");
JSONObject windI = channel.getJSONObject("wind");
JSONObject location = channel.getJSONObject("location");
String last = "";
last = location.getString("city");
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText(last);
}
When I run this app on device app crash.
It's error that write on Android Monitor:

All the network requests should be made on a separate worker thread or else you will get NetworkOnMainThread exception. For your use case use an Asynctask which has method doInBackground() to handle your request on background thread and post results back to main Ui thread inside onPostExecute() method. So call below method in in doInBackground() method.
getStringFromURL("https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='Esfahan')&format=json");
and use ui components like textview in onPostExecute() method
tv.setText(last);
which runs on ui thread. All this management is done by Asnyctask so you don't need to worry about thread management just know which method to use.
Asynctask Android documentation

In case of android there is one notion you have to follow, all time taking tasks need to go on a separate thread that is not blocking your UI thread. And all IO calls or heavy operation call should go onto a seperate thread.
For more about how to make network operations refer Android developer guide
here (https://developer.android.com/training/basics/network-ops/connecting.html) and follow this document.

Related

How can I share database android application and a .net web application?

I want to share database between an android application and a web application build using Asp.net (my database is based on an IIS server.)
I just want to find the possible ways available to do it, and if I could use php services with IIS server.
I would be so thankful if someone could help me.
Million ways. I can advise you this one: create REST or SOAP service which will have access to database with all methods you need. Now in android application and in ASP.NET application you can "ask" your service to create/update/delete/do something.
try with below code.Hope it will resolved your query.
/**
* This method is used for getting user response after sending request to server.
* It returns the response after executing url request.
* #param params
* #return
*/
public String getJSONObject(String params)
{
try
{
URL url = null;
String response = null;
String parameters = "param1=value1&param2=value2";
//url = new URL("http://www.somedomain.com/sendGetData.php");
url = new URL(params);
//create the connection
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setReadTimeout(40000);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
//set the request method to GET
connection.setRequestMethod("GET");
//get the output stream from the connection you created
OutputStreamWriter request = new OutputStreamWriter(connection.getOutputStream());
//write your data to the ouputstream
request.write(parameters);
request.flush();
request.close();
String line = "";
//create your inputsream
InputStreamReader isr = new InputStreamReader(
connection.getInputStream());
//read in the data from input stream, this can be done a variety of ways
BufferedReader reader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
//get the string version of the response data
response = sb.toString();
//do what you want with the data now
//always remember to close your input and output streams
isr.close();
reader.close();
}
catch (Exception e)
{
Log.e("HTTP GET:", e.toString());
response="";
}
return response;
}

Android Get json response of website call

there are some some web site that call end point and recive a json response.
I would like to know how in myAndroid app i can call the web site and retrive the json data that he show.
Example: this is a drivenow site map
drivenow map link
if i open debug mode of browser i see this ajax call that give a josn response.
I would like to know i can call this website and take (grap) this response in my android app so i can use the json
Any idea? Help?
Thanks
You can perform GET/POST request using two ways.
Some 3rd party network request libraries
I would suggest using robospice. Using robospice you perform a network request and give it a POJO. For more info on POJO refer to the link below
https://github.com/stephanenicolas/robospice/wiki/Starter-Guide
What is RoboSpice Library in android
Using native Android/Java code
Use this function to get JSON from URL.
public static JSONObject getJSONObjectFromURL(String urlString) throws IOException, JSONException {
HttpURLConnection urlConnection = null;
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader br=new BufferedReader(new InputStreamReader(url.openStream()));
char[] buffer = new char[1024];
String jsonString = new String();
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
jsonString = sb.toString();
System.out.println("JSON: " + jsonString);
return new JSONObject(jsonString);}
Then use it like this:
try{
JSONObject jsonObject = getJSONObjectFromURL(String urlString);
// Parse your json here
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
Do not forget to add Internet permission in your manifest
<uses-permission android:name="android.permission.INTERNET" />
For more info on parsing JSON visit
How to parse JSON in Android
Note
You don't have to manually parse your json if you use a 3rd party library.

Need to update the data the comming from one webservice in Async Task with other Async Task

I have an android activity where I am calling a web-service using AsyncTask and when the data is received success fully I need to update each row or item received form the web-service with the data coming from another web-service. This second web-service is called based on the data from first web-service. Its like this:
protected String doInBackground(String... params) {
try
{
String line="";
// String ur = "http://"+ServerDetails.hostServer+"/appservices.svc/TaskQuanityList?MaterialID=9336&ProjectNo=51&TaskNo=51." ;
String ur = "http://"+ServerDetails.hostServer+"/appservices.svc/grn?po="+PONum;
Log.d("URL", ur);
// Replace it with your own WCF service path
URL json = new URL(ur);
URLConnection jc = json.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(jc.getInputStream()));
line = reader.readLine().toString();
Log.d("LINE",line);
line=line.replace("\\\"", "\"");
line=line.substring(1, line.length()-1) ;
JSONArray array=new JSONArray(line);
for(int i=0; i < array.length(); i++) {
JSONObject tmpJson=array.getJSONObject(i);
lstdrpItem=new ArrayList<DropItem>();
StoreAsync storeasc=new StoreAsync();another webservice
storeasc.execute(tmpJson.getString("MaterialNo"));//-->Here I am calling second webservice
ItmGrn=new GrnData(tmpJson.getString("lblRowIdField"),tmpJson.getString("MaterialName"),tmpJson.getString("MaterialNo"),tmpJson.getString("RecievedQty"),tmpJson.getString("qty"),tmpJson.getString("Conversion_Factor"),tmpJson.getString("GRN_NO"),tmpJson.getString("Good_Qty"),tmpJson.getString("Retain_Qty"),tmpJson.getString("Rejected_Qty"),tmpJson.getString("Challan_Qty"),tmpJson.getString("RecStore_No"),tmpJson.getString("Brand_Id"),lstdrpItem);
lstGrn.add(ItmGrn);
Log.d("Material Name",tmpJson.getString("MaterialName"));
}
}
catch(Exception e)
{
Log.d("ERRROR--->",e.getMessage());
}
return "" ;
}
Now the issue is, it goes on executing the loop iterations without waiting for the second web-service. Now my question is how to make it wait until second web-service gets the data and continue with remaining iterations in the loop?

AsyncTask sanity check

I've been going over various Asynctask tutorials and examples, but I'm still a little confused. If I want to issue 3 web requests and return their response
like:
//example
String[] response = new String[3];
response[0] = webrequest("http://www.google.com"); //simple HTTP GET request
response[1] = webrequest("http://www.bing.com"); //simple HTTP GET request
response[2] = webrequest("http://www.aj.com"); //simple HTTP GET request
//sample results from request
response[0] = "blah";
response[1] = "arg";
response[2] = "meh";
To do this with an AsyncTask, would I need to implement 3 different ATs? Should I be using something else?
String[] response = new String[3];
webCreate sample = new webCreate();
try{
response[0] = sample.execute("http://www.google.com").get().toString();
response[1] = sample.execute("http://www.google.com").get().toString();
response[2] = sample.execute("http://www.google.com").get().toString();
}
catch (Exception sampleMsg)
{}
public class webCreate extends AsyncTask<String, String, String> {
}
protected String doInBackground(String... params) {
// String url=params[0];
String webRequestResponse = null; //the
// web request
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
return reponse;
}
I know I could access the response data by using .get(), but then my "Async" would become "sync" lol. I feel like I should be using something other than AsyncTask, but I have no idea what that is. Please help.
Your approach is okay, from doInBackground of your AsyncTask call a function that initiates the webrequests and wait for the result with . get(). Due to the fact, that the request are then, not running on the mainUi and blocking it, I see no problem in doing so.

Write JSON response to a text view

I am authenticating an external system via a REST API. The http authentication request is of the Basic Authorization form. The response is in JSON format.
I am running this code under an AsyncTask.
url The GET url of the API.
credentials is the authentication credentials. It is a string.
response is the text view.
getmessage is a string variable.
connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", "Basic" + Base64.encode(credentials.getBytes(), Base64.DEFAULT ));
// I am reading the response here,
InputStreamReader in = new InputStreamReader(connection.getInputStream());
buf = new BufferedReader(in);
getmessage = buf.readLine();
// After making the request, I am updating the response to a text view on the UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
response.setText(getmessage);
}
});
I am unable to write the whole JSON data to the text view. I know that buf.readline returns the response till the end of a line. Right now I am only getting a part of the JSON response, "Not Authenticated:", but I need the whole response.
How do I update the whole JSON response to the text view (response)? If I loop the data using buf.readline in a loop then where can I use it? In which thread?
If there is anything unusual in my code. Please let me know.
I would suggest you to go trough AsyncTask
private class GetDataFromUrl extends AsyncTask<URL, Integer, String> {
protected String doInBackground(URL... urls) {
connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", "Basic" + Base64.encode(credentials.getBytes(), Base64.DEFAULT ));
InputStreamReader in = new InputStreamReader(connection.getInputStream());
buf = new BufferedReader(in);
StringBuilder sb = new StringBuilder();
while ((getmessage = buf.readLine()) != null) {
sb.append(getmessage);
}
getmessage = sb.toString();
return getmessage;
}
protected void onPostExecute(String result) {
// Result will be available here (this runs on main thread)
// Show result in text view here.
response.setText(result);
}
}
To understand better, as you call AsyncTask, doInBackground runs on the new thread created. Where the network call in placed and data is parsed. Now, we need to access the data on the main thread to update the TextView so override onPostExecute inside AsyncTask that is taking result as a parameter, from doInBackground. Also if you notice..
private class GetDataFromUrl extends AsyncTask<URL, Integer, String>
Here URL is the type we are passing to our AsyncTask for doInBackground
String is what we passing from doInBackground to onPostExecute
and Integer is used to show progress for another method you can override i.e onProgressUpdate .. You can read more in the documentation liked above. Hope it was helpful.
You're only reading the first line of the response with readLine(). Call that in a loop until all lines are read, and append each new line to the previous.
If i understood correcly, you are trying to read all response data line by line. Can you try the following?
#Override
protected String doInBackGround(...){
. . .
BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream), 8 * 1024);
String line = "";
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
String response = sb.toString();
return response;
}
#Override
protected void onPostExecute(String response){
Textview tv = your_textview;
your_textview.settext(whatever_part_you_get_from_response);
}
Hope this helps.
Try this:
StringBuilder sb = new StringBuilder();
while ((getmessage = buf.readLine()) != null) {
sb.append(getmessage);
}
getmessage = sb.toString();
EDITED
In your code:
getmessage = buf.readLine();
in variable getmessage reads only first line of JSON. You need to read all lines and concatenate it. How to know did you read all lines or not?
Here is what documentation says about it:
public String readLine()
throws IOException
Returns:
A String containing the contents of the line, not including any
line-termination characters, or null if the end of the stream has been
reached
As you can see, you should invoke this method, save result of it into variable, and check, if variable is not null, then you have read line of JSON. If variable is null, then you have read all JSON into variable and you have completely JSON String.
StringBuilder used to avoid creating unnecessary objects, read more about it here

Categories

Resources