I have a method that should actually read the data from the web and returns the content as a String, but it is not working.I would be glad if you can help me out! I don't know where I screwed up. I added the INTERNET uses permission in the manifest file but doesn't work. Well, I tested on the emulator only.
public String getInternetData() throws Exception {
BufferedReader in = null;// read info
String response = null;
try {
HttpClient client = new DefaultHttpClient(); // default client
// process application to handle data from web
URI website = new URI("https://www.random.com");
// get information from web
HttpGet request = new HttpGet(); // get data
InputStream inputStream = null;
request.setURI(website);// connected and request
// respons
HttpResponse httpResponse = client.execute(request);
int statutCode = httpResponse.getStatusLine().getStatusCode();
int length = (int) httpResponse.getEntity().getContentLength();
inputStream = httpResponse.getEntity().getContent();
Reader reader = new InputStreamReader(inputStream, "UTF-8");
int inChar;
StringBuffer stringBuffer = new StringBuffer();
while ((inChar = reader.read()) != -1) {
stringBuffer.append((char) inChar);
}
response = stringBuffer.toString();
} finally {
}
return response;
}
I checked your code and it's working. I'm not sure if you are establishing a connection on your EDT or not but here's a template that's working with your code. Btw your link doesn't have a SSL, you need to connect to http.
package com.example.stackover;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#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;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
(new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
getInternetData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}).execute();
return rootView;
}
public void getInternetData() throws Exception {
BufferedReader in = null;// read info
String response = null;
try {
HttpClient client = new DefaultHttpClient(); // default client
// process application to handle data from web
URI website = new URI("http://www.random.com");
// get information from web
HttpGet request = new HttpGet(); // get data
InputStream inputStream = null;
request.setURI(website);// connected and request
// respons
HttpResponse httpResponse = client.execute(request);
int statutCode = httpResponse.getStatusLine().getStatusCode();
int length = (int) httpResponse.getEntity().getContentLength();
inputStream = httpResponse.getEntity().getContent();
Reader reader = new InputStreamReader(inputStream, "UTF-8");
int inChar;
StringBuffer stringBuffer = new StringBuffer();
while ((inChar = reader.read()) != -1) {
stringBuffer.append((char) inChar);
}
response = stringBuffer.toString();
} finally {
}
Log.v("Information", response);
}
}
}
Related
I've this condition to write the server call that executes every 50ms.
The server call must be from volley.
But the difficulty i am facing is every server call has different urls and how to pass these different urls in thread so to call server every 50ms.?
I am not an expert in android, but this is what I could think of if you want to call different urls after 50ms. Please correct me if I am wrong :)
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
int i=0;
final String[] urlArray = new String[]{"http://google.com","http://fb.com"};//your url array here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Runnable task = new Runnable() {
public void run() {
String currentURL= MainActivity.this.getNextURL();
new HitWebService().execute(currentURL);
}
};
worker.schedule(task, 50, TimeUnit.SECONDS);
}
private String getNextURL(){
String currentURL= urlArray[i];
if(i == urlArray.length){
i=0;
}
else{
i++;
}
return currentURL;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class HitWebService extends AsyncTask<String,Void,String> {
protected void onPreExecute(){
//do whatever you want with respect to ui
}
#Override
protected String doInBackground(String... params){
HttpURLConnection connection=null;
String stringUrl= params[0];
try {
URL url= new URL(stringUrl);
connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
DataOutputStream outputStream=new DataOutputStream(connection.getOutputStream());
String parameters = "initialise your parameters here, pass parameters also in params and access it like params[1]";
outputStream.writeBytes(parameters);
outputStream.flush();
outputStream.close();
InputStream inputStream=connection.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
StringBuffer response = new StringBuffer();
String line;
while((line=bufferedReader.readLine())!=null){
response.append(line);
}
bufferedReader.close();
return response.toString();
}
catch (MalformedURLException malformedException){
return malformedException.toString();
}
catch (IOException ioException){
return ioException.toString();
}
finally {
if(connection !=null){
connection.disconnect();
}
}
}
#Override
protected void onPostExecute(String response){
//do whatever you want here
}
}
}
Scenario
Users have to login to the server with this app. Later in the app we need to check their login status against the server. We used to do this by keeping track of the last used HttpClient. Recently we switched to HttpUrlConnection but the so-called persistent connections are not working.
Question
I wrote this test app to see if the connections were persistent. I get xml back from both URLs but the connection is not behaving like it's consistent. How can I get this to work?
Note: Everything works as expected if you go to the Login url in a browser and then go to the GetUserInfo url in the same browser.
MainActivity.java
package com.mediajackagency.test;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
public Button signInBtn = null;
public Button getUserInfoBtn = null;
public TextView xmlTextView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
this.xmlTextView = (TextView)findViewById(R.id.xmlTxtView);
this.signInBtn = (Button)findViewById(R.id.signInBtn);
this.signInBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AsyncTask task = new AsyncTask() {
#Override
protected Object doInBackground(Object[] params) {
String xml = loadUrl("https://www.fake.site/Login?userName=test&password=pass123");
return xml;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
xmlTextView.setText(o.toString());
}
};
task.execute();
}
});
this.getUserInfoBtn = (Button)findViewById(R.id.getUserInfoBtn);
this.getUserInfoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AsyncTask task = new AsyncTask() {
#Override
protected Object doInBackground(Object[] params) {
String xml = loadUrl("https://www.fake.site/GetCurrentUser");
return xml;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
xmlTextView.setText(o.toString());
}
};
task.execute();
}
});
}
public String loadUrl(String url) {
URI uri = MainActivity.encodeUrl(url);
Log.i("XMLParser", "Get URL: " + url);
String xml = null;
URL link;
BufferedReader reader = null;
StringBuilder stringBuilder = null;
InputStream is = null;
HttpURLConnection connection = null;
try {
link = new URL(url);
connection = (HttpURLConnection) link.openConnection();
connection.setRequestMethod("GET");
connection.connect();
is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is));
stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
stringBuilder.append(line + "\r");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
if(reader != null) reader.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if(is != null) is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if(connection != null) connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
try {
xml = stringBuilder.toString();
} catch(Exception e) {
e.printStackTrace();
}
return xml;
}
public static URI encodeUrl(String url) {
URL urlObject;
URI uri = null;
try {
urlObject = new URL(url);
uri = new URI(urlObject.getProtocol(), urlObject.getUserInfo(), urlObject.getHost(),
urlObject.getPort(), urlObject.getPath(), urlObject.getQuery(), urlObject.getRef());
} catch (Exception e) {
e.printStackTrace();
}
return uri;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Solved With Cookies
After days / hours of working on this I found that persistent connections (http.keepalive) with HttpUrlConnection is not all it's cracked up to be:
1) You need to make sure the InputStream and HttpUrlConnection are closed before you can reuse the connection and even then it may not always be reusable.
2) Open TCP connections can be resource hogs.
After finding & testing the idea of using cookies with HttpUrlConnection I decided to go that route as it's fundamentally more sound and performs better than my original idea.
I am trying to invoke the POST API of personality insights from Android on a button click and display the response on the screen after proper parsing. The API details of the personality insights are here.
When I tried to test this using POSTMAN I am getting the correct response. But when I try to invoke this from Android, the logcat is not showing any error and the application doesn't terminate in the emulator. The initial invocation of API is not working for me.
I referred this link for the android code
This is the code which I used. Please let me know of any mistakes that I have made.
Edited :
I also tried this example link but everything seems to be deprecated for my current android API versions.
HTTP Example.java
package com.example.httpexample;
import android.support.v7.app.AppCompatActivity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView textView, button;
TextView textView1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView1);
button = (TextView)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener(){
// When user clicks button, calls AsyncTask.
// Before attempting to fetch the URL, makes sure that there is a network connection.
#Override
public void onClick(View v) {
String stringUrl = "https://gateway.watsonplatform.net/personality-insights/api/v2/profile" (https://gateway.watsonplatform.net/personality-insights/api/v2/profile%27);
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageTask().execute(stringUrl);
} else {
textView.setText("No network connection available.");
}
}
});
}
public TextView getTextView()
{
TextView txtView = (TextView)findViewById(R.id.textView2);
return txtView;
}
#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;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
DownloadWebpageTask.java
package com.example.httpexample;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Log;
import android.widget.TextView;
class DownloadWebpageTask extends AsyncTask<String, Void, String> {
private static final String DEBUG_TAG = "HttpExample";
#Override
protected String doInBackground(String... urls) {
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public String downloadUrl(String myurl) throws IOException, JSONException{
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//conn.setRequestMethod("GET");
final String basicAuth = "Basic " + Base64.encodeToString(""username":password".getBytes(), Base64.NO_WRAP);
conn.setRequestProperty ("Authorization", basicAuth);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.connect();
System.out.println("first connection");
JSONObject contentItems = new JSONObject();
contentItems.put("id", "");
contentItems.put("userid", "");
contentItems.put("created", "int");
contentItems.put("updated", "int");
contentItems.put("contenttype", "");
contentItems.put("charset", "");
contentItems.put("language", "int");
contentItems.put("content", "Hi. This is the sample input");
contentItems.put("parentid", "");
contentItems.put("reply", false);
contentItems.put("forward", false);
System.out.println("connection done");
int response = conn.getResponseCode();
Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
System.out.println("Content " + contentAsString);
MainActivity obj = new MainActivity() ;
TextView tv = obj.getTextView();
tv.setText(contentAsString + response);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
private String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}
It does not seem you are sending your contentItems object anywhere - you populate it, but never include it as payload in the request.
In addition, this contentItems is just one item object you need to include in the JSON input. The JSON input should look like:
{ "contentItems": [ <item1>, <item2> ] }
and you are just creating something that fits as one of the items above.
If you are passing some simple input to the API, I would suggest you include the header Content-Type: text/plain and forget about JSON formatting for the moment, as it is going to be simpler.
I was trying to load a web page on the emulator. I was trying the following code.
package com.test.scraptest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.TextView01);
}
#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;
}
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
Log.e("MYAPP", "exception", e);
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
public void onClick(View view) {
DownloadWebPageTask task = new DownloadWebPageTask();
// new Toast(getApplicationContext());
Toast ts=Toast.makeText(this, "this is a message",Toast.LENGTH_SHORT) ;
ts.show();
task.execute(new String[] { "http://www.google.com" });
}
}
Problem is, when I run the application I get the following error.
I am currently trying to DL some twitter information and for some reason the code that I am using will not return the data.
When I use the URL manually in Explorer I do get data. but when I try to get Android to do it I get an exception.
I have found two ways of trying to get at the data. The first is as shown. The second is commenting out the three lines above the comments and uncommenting the other lines.
I will be using JSON simple afterwards in order to parse the string.
I hope I have explained my issue sufficiently. Any comments would be welcome.
import java.io.InputStream;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String searchUrl = "http://search.twitter.com/search.json?q=#aplusk&rpp=100&page=1";
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(searchUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = null;
Log.d("log", "test"+responseBody);
try{
responseBody = client.execute(get, responseHandler);
HttpResponse response = client.execute(get);
responseBody = response.toString();
// HttpResponse response = client.execute(get);
// InputStream inputStream = response.getEntity().getContent();
// responseBody = inputStream.toString();
Log.d("log", "test2"+responseBody);
}catch(Exception ex) {
Log.d("log", "nope");
ex.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
I'm not sure what your exception is, but your first problem is probably that you're doing network activity on the main thread. You'll have to spin up a new thread or use an Async Task.
Your second problem is you're improperly converting the response to a string. To get the actual content string you'll have to iterate over an InputStream. This is my preferred method.
Also, make sure <uses-permission android:name="android.permission.INTERNET" /> is in your AndroidManifest.xml file.
Try this out:
import java.io.InputStream;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
(new Thread(new Runnable() {
#Override
public void run() {
String searchUrl = "http://search.twitter.com/search.json?q=#aplusk&rpp=100&page=1";
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(searchUrl);
String responseBody = null;
Log.d("log", "test" + responseBody);
try {
HttpResponse response = client.execute(get);
InputStream inputStream = response.getEntity().getContent();
// responseBody = inputStream.toString();
responseBody = streamToString(inputStream);
Log.d("log", "test2" + responseBody);
} catch (Exception ex) {
Log.d("log", "nope");
ex.printStackTrace();
}
}
})).start();
}
public static String streamToString(InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
#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;
}
}