Parsing Twitter API 1.1 JSON - java

I've been working on an open source code of a Twitter reader (read only) (oauth 2.0) that pulls JSON from a user timeline. It successfully pulls the JSON from Twitter API 1.1. The challenge I'm facing is converting that JSON into something user friendly. I've implemented sections of another source code that focused on parsing the JSON, but I'm not very familiar with parsing JSON. It's patchwork so I know I might be overlooking something. Possibly a redundancy or missing part.
UPDATED:
When I run the app, it doesn't crash, it's just stuck at "Got Token!". What I'm hoping to display is a list of tweets somewhat formatted to look like one. I believe it's the MainActivity, but I could be wrong. You will need a Consumer Key and Secret to test. I'll put up what I have at the moment, but if anyone knows how I can get out of that loop, I'd appreciate your input.
Thanks!
MainActivity.java
package com.example.readtwitterfeed;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.json.JSONObject;
import org.json.simple.JSONArray;
import org.json.simple.JSONValue;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Base64;
import android.util.Log;
import android.widget.TextView;
import com.example.readtwitterfeed.R;
public class MainActivity extends Activity {
// CONSUMER API KEY - 21 characters (go here to get one: https://dev.twitter.com/apps/)
// **** CHANGE THIS ****
static final String twitterAPIKEY = "################";
// CONSUMER SECRET - 41 characters (go here to get one: https://dev.twitter.com/apps/)
// **** CHANGE THIS ****
static final String twitterAPISECRET = "###############################";
static final String twitterAPIurl = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=";
// Twitter 'Screen Name'
// **** CHANGE THIS ****
static final String screenName = "Insert_Username_Here";
// Tweets to return
// **** CHANGE THIS, if needed ****
static final int tweets2Return = 1;
// Final URL will look like this (# is your sreen name/return tweets):
// https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=###&include_rts=1&count=#
static String tweeterURL = twitterAPIurl + screenName
+ "&include_rts=1&count=" + tweets2Return;
static String twitterToken = null;
static String jsonTokenStream = null;
static String jsonFeed = null;
static String tweetJSON = null;
TextView twitterText;
// ////////////////////////////////////
// onCreate - Let's get the GUI going
// ////////////////////////////////////
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
twitterText = (TextView) findViewById(R.id.tweetFeed);
// Call first AsyncTask
new loadTwitterToken().execute();
}
// ////////////////////////////////////////////////////////////////////
// AsyncTask - First, let's get our Token for oAuth (from Twitter)
// If you need oAuth help: https://dev.twitter.com/docs/auth/oauth/faq/
// ////////////////////////////////////////////////////////////////////
protected class loadTwitterToken extends AsyncTask<Void, Void, Integer> {
#Override
protected Integer doInBackground(Void... params) {
//As of this writing, Twitter says, "We do not currently expire access tokens."
try {
DefaultHttpClient httpclient = new DefaultHttpClient(
new BasicHttpParams());
HttpPost httppost = new HttpPost(
"https://api.twitter.com/oauth2/token");
String apiString = twitterAPIKEY + ":" + twitterAPISECRET;
String authorization = "Basic "
+ Base64.encodeToString(apiString.getBytes(),
Base64.NO_WRAP);
httppost.setHeader("Authorization", authorization);
httppost.setHeader("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
httppost.setEntity(new StringEntity(
"grant_type=client_credentials"));
InputStream inputStream = null;
// Let's send to web
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
// Our response
inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
// Will look like this:
// {"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAABiQTgAAAAAACGie2o%2Bm7jNnxw8txVG99c1wAU8%3DmZq7qrX8JZpDFrgYyh5gLtOkJhQ7BvPD6bZ0ssitjg"}
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
jsonTokenStream = sb.toString();
// onPostExecute likes to get a parameter passed to work right.
// Just passing something.
return 1;
} catch (Exception e) {
Log.e("loadTwitterToken",
"doInBackground Error:" + e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(Integer result) {
// Extract Token from JSON stream
try {
JSONObject root = new JSONObject(jsonTokenStream);
twitterToken = root.getString("access_token");
} catch (Exception e) {
Log.e("loadTwitterToken", "onPost Error:" + e.getMessage());
}
twitterText.setText("Got Token!");
// Now that we have a oAuth Token, lets get our JSON feed from twitter.
// We call it from here to make sure the Token has been received already.
new loadTwitterFeed().execute();
}
}
// ///////////////////////////////////////////////////////////
// AsyncTask - Download Twitter Feed w/Token as authorization
// //////////////////////////////////////////////////////////
protected class loadTwitterFeed extends AsyncTask<Void, Void, Integer> {
#Override
protected Integer doInBackground(Void... params) {
BufferedReader reader =null;
try{
DefaultHttpClient httpclient = new DefaultHttpClient(
new BasicHttpParams());
HttpGet httpget = new HttpGet(tweeterURL);
httpget.setHeader("Authorization", "Bearer " + twitterToken);
httpget.setHeader("Content-type", "application/json");
InputStream inputStream = null;
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
reader = new BufferedReader(
new InputStreamReader(inputStream, "UTF-8"), 8);
return null;
} catch (ClientProtocolException 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 null;
}
protected void onPostExecute(String result) {
StringBuilder sb = new StringBuilder();
try{
JSONObject resultObject = new JSONObject(result);
org.json.JSONArray tweetArray = resultObject.getJSONArray("results");
for (int t=0; t<tweetArray.length(); t++) {
JSONObject tweetObject = tweetArray.getJSONObject(t);
sb.append(tweetObject.getString("from_user")+": ");
sb.append(tweetObject.get("text")+"\n\n");
}
}
catch (Exception e) {
Log.e("Tweet", "Error retrieving JSON stream" + e.getMessage());
jsonFeed = sb.toString();
e.printStackTrace();
}
}
}
/*String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}*/
protected void onPostExecute(Integer result) {
// Update GUI
if (jsonFeed.length() > 0) {
twitterText.setText(jsonFeed);
} else {
//I'd assume wrong Consumer Key/Secret if this happens.
twitterText.setText("Nothing Returned");
}
}
}
Activity_Main.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tweetFeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Loading..." />
</ScrollView>

You forgot to close the ProgressDialog in onPostExecute method.
just do this pd.dismiss(); in onPostExecute like this.
#Override
protected void onPostExecute(Integer result) {
pd.dismiss();
// Extract Token from JSON stream
try {
JSONObject root = new JSONObject(jsonTokenStream);
twitterToken = root.getString("access_token");
} catch (Exception e) {
Log.e("loadTwitterToken", "onPost Error:" + e.getMessage());
}
twitterText.setText("Got Token!");
// Now that we have a oAuth Token, lets get our JSON feed from twitter.
// We call it from here to make sure the Token has been received already.
new loadTwitterFeed().execute();
}

Related

update/create JSON object on button press

im am currently creating a CMS applicationa and i am trying to create a JSON object that i can post to my API but i have no idea on how to do this because im new to android. does anyone have an Idea?
My code:
String URL = "http://test.soundwave.drieo.nl/api/content/" + uid + "?apikey=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
try {
APIClientJSONObject api = new APIClientJSONObject();
JSONObject result = null;
try {
result = api.execute(URL).get();
} catch (Exception e) {
e.printStackTrace();
}
try {
String content = result.optString("FormattedName");
String content2 = result.optString("Title");
String content3 = result.optString("Subtitle");
String content4 = result.optString("Text");
EditText name = (EditText) findViewById(R.id.etInternNaam);
name.setText(content);
EditText titel = (EditText) findViewById(R.id.etName);
titel.setText(content2);
EditText ondertitel = (EditText) findViewById(R.id.etOndertitel);
ondertitel.setText(content3);
EditText EditText = (EditText) findViewById(R.id.etTekst);
EditText.setText(Html.fromHtml(content4));
if("null" == content) {
name.setText("");
}
if("null" == content2) {
titel.setText("");
}
if("null" == content3) {
ondertitel.setText("");
}
if("null" == content4) {
EditText.setText("");
}
} catch (Exception e) {
e.printStackTrace();
}
API code:
package nl.drieo.soundwave.test.cms;
import android.os.AsyncTask;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import cz.msebera.android.httpclient.HttpResponse;
import cz.msebera.android.httpclient.client.HttpClient;
import cz.msebera.android.httpclient.client.methods.HttpGet;
import cz.msebera.android.httpclient.impl.client.DefaultHttpClient;
/**
* Created by r.devries on 14-3-2016.
*/
public class APIClientJSONObject extends AsyncTask<String, Void, JSONObject> {
#Override
protected JSONObject doInBackground(String... params) {
JSONObject result = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpResponse = httpclient.execute(new HttpGet(params[0]));
InputStream inputStream = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
result = new JSONObject(builder.toString());
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
you can create JSONObject like this and put your data into that:
JSONObject json = new JSONObject();
json.put("user", "example");
after putting your data to json, you can pass the json to the 'APIClientJSONObject' class by this way:
EDIT: use this code in to OnClickListener for your Button
try {
result = api.execute(URL,json.toString()).get();
} catch (Exception e) {
e.printStackTrace();
}
and you can get Json in 'APIClientJSONObject' class like this:
JSONObject jsonObject = new JSONObject(params[1])
or if you want 'POST' this json to the webservice, you can use: EDIT: use this in to the APIClientJSONObject class in doInBackground method:
HttpPost httpost = new HttpPost(params[0]);
StringEntity stringentity = new StringEntity(params[1]);
httpost.setEntity(stringentity);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
ResponseHandler responseHandler = new BasicResponseHandler();
httpclient.execute(httpost, responseHandler);
I hope these code are useful for you.

HttpURLConnection working in Java but not android

We've been trying to send a POST request to a node.js server in an android app. Because the old apache dependencies are deprecated (and I can't seem to access them - I've tried) we've been using the HttpURLConnection classes. We've coded a class in java that works as just a standalone class (Request.java) but when incorperated in the android program, it throws an error every time and when trying to get the message of the error, it just returns null.
Request.java
package andrewmmattb.beacongame;
/**
* Created by matt on 05/03/2016.
*/
import java.net.HttpURLConnection;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
public class Request {
public static void main(String[] args) throws Exception {
Request http = new Request();
System.out.println("POST");
http.sendPost("{\"username\": \"matt\",\"newPoints\":5}");
}
public static void sendPost(String json) throws Exception {
String url = "http://ec2-54-187-69-193.us-west-2.compute.amazonaws.com/points";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("Content-Type", "application/json");
String urlParameters = "";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(json);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
}
}
GameActivity.java
package andrewmmattb.beacongame;
import android.app.Activity;
import android.app.DownloadManager;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.util.Base64;
import android.util.JsonWriter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import org.json.*;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class GameActivity extends Activity {
String username;
String serverPath = "THE PATH TO THE SERVER";
int score = 0;
int prevScore = 0;
TextView usernameTextView;
TextView scoreTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
usernameTextView = (TextView)findViewById(R.id.textViewGameUsername);
scoreTextView = (TextView)findViewById(R.id.textViewGameScore);
Intent intent = getIntent();
username = intent.getStringExtra("username");
usernameTextView.setText(username);
try {
makeSeverPost();
}
catch (IOException e) {
Toast.makeText(GameActivity.this,"There was an IO error, called after function call (line 56)",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
void makeSeverPost() throws IOException {
// creates a map object with username and the additional points to the previous sent score
Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);
// sets the previous score to equal the current score
prevScore = score;
// writes the map into a string in JSON format
String jsonString = new JSONObject(values).toString();
try {
Request.sendPost(jsonString);
} catch (Exception e) {
e.printStackTrace();
Log.e("problem",""+e.getMessage());
}
}
}
There are many redundant dependancies due to all the other attempts to do this we've made.
In android network on main thread are not allowed.
You have to call this method from an AsyncTask.
Example:
class MakeSeverPostTask extends AsyncTask<Void, String, JSONObject>
{
Map<String,Object> params;
public MakeSeverPostTask(Map<String,Object> params){
this.params = params;
}
protected JSONObject doInBackground(Void... v)
{
String jsonString = new JSONObject(this.params).toString();
return Request.sendPost(jsonString);
}
protected void onPostExecute(JSONObject result)
{
}
}
Usage:
Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);
new MakeSeverPostTask(values).execute();
Here is more elaborated solution:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
usernameTextView = (TextView)findViewById(R.id.textViewGameUsername);
scoreTextView = (TextView)findViewById(R.id.textViewGameScore);
// creates a map object with username and the additional points to the previous sent score
Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);
// writes the map into a string in JSON format
String jsonString = new JSONObject(values).toString();
String url = "http://ec2-54-187-69-193.us-west-2.compute.amazonaws.com/points";
// executing AsyncTask with passing string parameters.
ServerAsyncTask makeServerPost = new ServerAsyncTask();
makeServerPost.execute(url, jsonString);
}
private class ServerAsyncTask extends AsyncTask<String, Void, JSONObject> {
private final String TAG = ServerAsyncTask.class.getSimpleName();
#Override
protected JSONObject doInBackground(String... params) {
JSONObject result = null;
try {
URL obj = new URL(params[0]); // added url
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("Content-Type", "application/json");
String urlParameters = "";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(params[1]); // Added json
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
Log.i(TAG, "\nSending 'POST' request to URL : " + params[0]);
Log.i(TAG, "Post parameters : " + urlParameters);
Log.i(TAG, "Response Code : " + responseCode);
// safer way to parse response
if(responseCode == HttpURLConnection.HTTP_OK){
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
Log.i(TAG, response.toString());
result = new JSONObject(response.toString());
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
/* You get response jsonObject here,
you can now update your UI here*/
// Example update your score.
try {
String score = (String) jsonObject.get("score");
scoreTextView.setText(score);
} catch (JSONException e) {
e.printStackTrace();
}
}
}

external database connection on web host not working

i followed a tutorial of login/register on android studio (toni kami tutorial) , i did all of what he did , but the httpclient /httpparams method is no longer working on android studio , im new to app programming so i searched the internet for a way to work this problem , i found a url connection code , i copy it but its not working .
****** this is all the java class ******
------ help me by correcting this or give me a new idea to work it out ------
when i run the app i get this :
package com.thenewboston.loginr;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* Created by sleeman on 1/1/16.
*/
public class ServerRequests {
ProgressDialog progressDialog;
public static final int CONNECTION_TIMEOUT = 1000 * 15;
public static final String SERVER_ADDRESS = "http://sleemanb94.tk/";
public ServerRequests(Context context){
progressDialog = new ProgressDialog(context);
progressDialog.setCancelable(false);
progressDialog.setTitle("Processing");
progressDialog.setMessage("Please Wait...");
}
public void storeUserDataInBackground(User user, getUserCallBack userCallback){
progressDialog.show();
new StoreUserDataAsyncTask(user,userCallback).execute();
}
public void fetchUserDataInBackground(User user, getUserCallBack callback) {
progressDialog.show();
new fetchUserDataAsyncTask(user, callback).execute();
}
public class StoreUserDataAsyncTask extends AsyncTask<Void, Void, Void>{
User user;
getUserCallBack userCallback;
public StoreUserDataAsyncTask(User user, getUserCallBack userCallback){
this.user = user;
this.userCallback = userCallback;
}
#Override
protected Void doInBackground(Void... params) {
Map<String,String> dataToSend = new HashMap<>();
dataToSend.put("fname", user.fname);
dataToSend.put("lname", user.lname);
dataToSend.put("email", user.email);
dataToSend.put("password", user.password);
//Server Communication part - it's relatively long but uses standard methods
//Encoded String - we will have to encode string by our custom method (Very easy)
String encodedStr = getEncodedData(dataToSend);
//Will be used if we want to read some data from server
BufferedReader reader = null;
//Connection Handling
try {
//Converting address String to URL
URL url = new URL(SERVER_ADDRESS + "Register.php");
//Opening the connection (Not setting or using CONNECTION_TIMEOUT)
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//Post Method
con.setRequestMethod("POST");
//To enable inputting values using POST method
//(Basically, after this we can write the dataToSend to the body of POST method)
con.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
//Writing dataToSend to outputstreamwriter
writer.write(encodedStr);
//Sending the data to the server - This much is enough to send data to server
//But to read the response of the server, you will have to implement the procedure below
writer.flush();
//Data Read Procedure - Basically reading the data comming line by line
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while((line = reader.readLine()) != null) { //Read till there is something available
sb.append(line + "\n"); //Reading and saving line by line - not all at once
}
line = sb.toString(); //Saving complete data received in string, you can do it differently
//Just check to the values received in Logcat
Log.i("custom_check", "The values received in the store part are as follows:");
Log.i("custom_check",line);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
private String getEncodedData(Map<String,String> data) {
StringBuilder sb = new StringBuilder();
for(String key : data.keySet()) {
String value = null;
try {
value = URLEncoder.encode(data.get(key), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if(sb.length()>0)
sb.append("&");
sb.append(key + "=" + value);
}
return sb.toString();
}
#Override
protected void onPostExecute(Void aVoid) {
progressDialog.dismiss();
userCallback.done(null);
super.onPostExecute(aVoid);
}
}
public class fetchUserDataAsyncTask extends AsyncTask<Void, Void, User> {
User user;
getUserCallBack userCallback;
public fetchUserDataAsyncTask(User user, getUserCallBack userCallback) {
this.user = user;
this.userCallback = userCallback;
}
#Override
protected User doInBackground(Void... params) {
//Use HashMap, it works similar to NameValuePair
Map<String, String> dataToSend = new HashMap<>();
dataToSend.put("email", user.email);
dataToSend.put("password", user.password);
//Server Communication part - it's relatively long but uses standard methods
//Encoded String - we will have to encode string by our custom method (Very easy)
String encodedStr = getEncodedData(dataToSend);
//Will be used if we want to read some data from server
BufferedReader reader = null;
//Connection Handling
User returnedUser = null;
try {
//Converting address String to URL
URL url = new URL(SERVER_ADDRESS + "FetchUserData.php");
//Opening the connection (Not setting or using CONNECTION_TIMEOUT)
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//Post Method
con.setRequestMethod("POST");
//To enable inputting values using POST method
//(Basically, after this we can write the dataToSend to the body of POST method)
con.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
//Writing dataToSend to outputstreamwriter
writer.write(encodedStr);
//Sending the data to the server - This much is enough to send data to server
//But to read the response of the server, you will have to implement the procedure below
writer.flush();
//Data Read Procedure - Basically reading the data comming line by line
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = reader.readLine()) != null) { //Read till there is something available
sb.append(line + "\n"); //Reading and saving line by line - not all at once
}
line = sb.toString(); //Saving complete data received in string, you can do it differently
//Just check to the values received in Logcat
Log.i("custom_check", "The values received in the store part are as follows:");
Log.i("custom_check", line);
returnedUser = new User( user.fname, user.lname);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
return returnedUser;
}
#Override
protected void onPostExecute(User returnedUser) {
progressDialog.dismiss();
userCallback.done(returnedUser);
super.onPostExecute(returnedUser);
}
private String getEncodedData(Map<String, String> data) {
StringBuilder sb = new StringBuilder();
for (String key : data.keySet()) {
String value = null;
try {
value = URLEncoder.encode(data.get(key), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (sb.length() > 0)
sb.append("&");
sb.append(key + "=" + value);
}
return sb.toString();
}
}
}
HttpClient is deprecated. But you can use it in android studio easily
Check this answer

How to parse JSON with AsyncTask?

I tried to parse some strings from this JSON-site:
I wrote this code with asynctask:
package com.example.nortti.jsonexample;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class MainActivity extends Activity {
TextView txView;
//URL to get JSON Array
private static String url = "http://localhost:10101/api/stats/1";
//JSON Node Names
private static final String TAG_USER = "";
private static final String TAG_NAME = "PersonName";
private static final String TAG_EMAIL = "Rank";
JSONArray user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
user = null;
new JSONParse().execute();
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
txView = (TextView)findViewById(R.id.txView);
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... args) {
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);
return json;
}
#Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
try {
// Getting JSON Array
user = json.getJSONArray("ArrayOfCommonStatViewModel");
Toast.makeText(getApplication(),user.toString(),Toast.LENGTH_SHORT).show();
JSONObject c = user.getJSONObject(0);
// Storing JSON item in a Variable
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
//Set JSON Data in TextView
txView.setText(name+" " +email);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
And I have another class like:
import android.util.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
But it says that I have a NullPointerException
I want to get a JSONArray to get information and put it into a ListView.
UPD: Here is JSON screenshot
UPD2: full log
12-17 14:17:03.712 20308-20308/com.example.nortti.politrange E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nortti.politrange, PID: 20308
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at org.apache.http.impl.conn.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:44)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:102)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:373)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:225)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:178)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at com.example.nortti.politrange.utils.WebApiAdapter.select(WebApiAdapter.java:33)
at com.example.nortti.politrange.intefaces.impls.PersonCatalog.populateData(PersonCatalog.java:37)
at com.example.nortti.politrange.views.GeneralFragment.listData(GeneralFragment.java:65)
at com.example.nortti.politrange.views.GeneralFragment.onClick(GeneralFragment.java:88)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19761)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5253)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
you are getting a NetworkOnMainThread exception because you are implementing a network operation in a UI thread so for loading the json data from your localhost you need to implement a seperate thread for it
You are getting NetworkOrMainThreadException.
Put below code on onCreate():
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Hope this will help you.
You are trying to parse an XML document with a JSON Parser, it won't work. Let's take a look on this link , it will show you how to parse an XML document (in Android environment) on a proper way:
The content that you are trying to parse is actually xml not JSON. If you need to do network requests, parse the JSON, you can use Retrofit library. It is very simple and hassle-free. Here is a nice tutorial for the same. Hope it helps.
instead of developping the whole parsing code, try to use the Volley library of Google, it's an asynchrone library for parsing JSON.
here is a good tutorial.
enter code here
////In android studio add http client and http core libs/////
class mytask extends AsyncTask {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
String url = "http://192.168.1.13/mywebservice/getbook.php";
json = getJSONFromUrl(url);
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Toast.makeText(ctx, json, Toast.LENGTH_LONG).show();
parser_01();
}
}
// from url to json object starts.......................................
public String getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
// sb.append(line + "n");
sb.append(line);
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
return json;
}
// from url to json object Ends.......................................
public void parser_01() {
try {
String jstring = json;
JSONObject jobject = new JSONObject(jstring);
JSONArray bookarray = jobject.getJSONArray("data");
for (int i = 0; i < bookarray.length(); i++) {
String isdn = bookarray.getJSONObject(i).getString("isdn") + "";
String title = bookarray.getJSONObject(i).getString("title") + "";
String author = bookarray.getJSONObject(i).getString("author") + "";
String price = bookarray.getJSONObject(i).getString("price") + "";
}
} catch (Exception e) {
// TODO: handle exception
}
}

Cast String to List<NameValuePair>

I'm basically trying to pass a List<NameValuePair> to an external class that handles POST HTTPRequest on an Android app.
String[] args = new String[]{"http://url/login", nameValuePairs.toString()}; //nameValuePairs is a param list to send via POST
Log.i("params", nameValuePairs.toString());
try {
String text = new rest().execute(args).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The doInBackgroud of the ASyncTask receives two parameters (the url for the request and the result of nameValuePairs.toString()), and I cannot find a way to convert the string back to a List< NameValuePair >.
Any ideas?
I bring you an example of how to consume REST services by POST or GET, sets the List< NameValuePair > as parameters and then parse the response to a string that can then be used as suits you (JSON, XML, or a data frame)
import java.io.*;
import java.util.*;
import org.apache.http.*;
import org.apache.http.client.*;
import org.apache.http.client.entity.*;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.*;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
public class RESTHelper {
private static final String URL_POST = "http://url/login";
private static final String URL_GET = "http://url/login";
public static String connectPost(List<BasicNameValuePair> params){
String result = "";
try{
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(URL_POST);
request.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
}
}catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static String connectGet(List<BasicNameValuePair> params){
String result = "";
try{
String finalUrl = URL_GET + URLEncodedUtils.format(params, null);
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(finalUrl);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
}
}catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
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();
}
}
You can't, unless you write some sort of converter that pulls apart a known format, e.g., nvp[0].name=xxx, nvp[0].value=zzz etc. or re-structures the default toString output (not fun).
Normally you'd use JSON, XML, etc. instead of List.toString.
Or use an actual HTTP client library.
If you execute a code like this:
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
....
List<NameValuePair> h = new ArrayList<NameValuePair>();
h.add(new BasicNameValuePair("a", "b"));
h.add(new BasicNameValuePair("c", "d"));
Log.d("jj", h.toString());
you can see that the output is something like:
[a=b, c=d]
so you can write a parser (or maybe using split()) to restore the List.
However I think it's not a good idea to rely on the implementation of toString in ArrayList and NameValuePair, and use another kind of serialization method, like JSON as Dave said.

Categories