Android: Downloading HTML not always working - java

In my app, I download the HTML Stylesheet of a website, using this code:
private DefaultHttpClient createHttpClient() {
HttpParams my_httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(my_httpParams, 3000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ThreadSafeClientConnManager multiThreadedConnectionManager = new ThreadSafeClientConnManager(my_httpParams, registry);
DefaultHttpClient httpclient = new DefaultHttpClient(multiThreadedConnectionManager, my_httpParams);
return httpclient;
}
private class Example extends AsyncTask<Void, Void, Void> {
int mStatusCode = 0;
String content = "";
#Override
protected Void doInBackground(Void... args) {
String url = "www.example.com";
DefaultHttpClient httpclient = createHttpClient();
HttpGet httpget = new HttpGet(url);
try {
HttpResponse response = httpclient.execute(httpget);
StatusLine statusLine = response.getStatusLine();
mStatusCode = statusLine.getStatusCode();
if (mStatusCode == 200){
content = EntityUtils.toString(response.getEntity());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void arg) {
//Stuff
}
}
However, sometimes, especially when the phone is on 3g, I'm getting mStatusCode = 0, while other internet apps such a the browser still work.
Do you guys know how I could prevent this from happening?
Many many thanks in advance!!

For parsing html you can use jsoup - Java HTML Parser. For example:
String url = "http://www.google.com";
Document doc = Jsoup.connect(url).get();
Elements img = doc.select("img");
Elements js = doc.select("script");
// Save images
for (Element el : img)
{
String imageUrl = el.attr("src");
FileUtils.saveFile("url", "File", "Folder");
}
// Save JS
for (int j = 0; j < js.size() - 1; j++)
{
String jsUrl = js.get(j).attr("src");
FileUtils.saveFile("url", "File", "Folder");
}
// The same for CSS
For saving file:
public static void saveFile(String fileUrl, String fileName,
String folderName) throws IOException
{
URL url = new URL(fileUrl);
InputStream input = url.openStream();
File extStorageDirectory = Environment.getExternalStorageDirectory();
File folder = new File(extStorageDirectory, folderName);
folder.mkdir();
OutputStream output = new FileOutputStream(new File(folder, fileName));
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0)
{
output.write(buffer, 0, bytesRead);
}
output.close();
input.close();
}
For checking network availability you can use this method:
public static boolean checkIfURLExists(String host, int seconds)
{
HttpURLConnection httpUrlConn;
try
{
httpUrlConn = (HttpURLConnection) new URL(host).openConnection();
// Set timeouts in milliseconds
httpUrlConn.setConnectTimeout(seconds * 1000);
httpUrlConn.setReadTimeout(seconds * 1000);
// Print HTTP status code/message for your information.
System.out.println("Response Code: " + httpUrlConn.getResponseCode());
System.out.println("Response Message: "
+ httpUrlConn.getResponseMessage());
return (httpUrlConn.getResponseCode() == HttpURLConnection.HTTP_OK);
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
return false;
}
}

Related

Call asmx HTTP POST from android

I'm trying to post HTTP from android. If I'll request using that C# code in LINQPAD it works
void Main()
{
string r = String.Format(#"<s:Body><TrackMobileApp xmlns=""soap action url"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><device>test</device><imei>test</imei><ipAddress>127.0.0.1</ipAddress><timeStamp>2016-02-17T17:32:00.5147663+04:00</timeStamp></TrackMobileApp></s:Body>", DateTime.Now.ToString("o"));
HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create("URL.asmx");
wr.ProtocolVersion = HttpVersion.Version11;
wr.Headers.Add("SOAPAction", "soap action");
wr.Method = "POST";
wr.ContentType = "text/xml;charset=utf-8";
using (StreamWriter sw = new StreamWriter(wr.GetRequestStream()))
{
sw.Write(r);
}
HttpWebResponse rs = (HttpWebResponse)wr.GetResponse();
if (rs.StatusCode == HttpStatusCode.OK)
{
XmlDocument xd = new XmlDocument();
using (StreamReader sr = new StreamReader(rs.GetResponseStream()))
{
xd.LoadXml(sr.ReadToEnd());
xd.InnerXml.Dump();
}
}
}
But from android it gives me http 415. What's wrong?
I have this in onCreate
new DownloadTask().execute("URL.asmx");
and my methods are:
private class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//do your request in here so that you don't interrupt the UI thread
try {
return downloadContent(params[0]);
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
//Here you are done with the task
}
}
private String downloadContent(String myurl) throws IOException {
InputStream is = null;
int length = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestProperty("SOAPAction", "soap action");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/xml");
conn.setDoInput(true);
conn.connect();
int response = conn.getResponseCode();
Log.d(TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = convertInputStreamToString(is, length);
return contentAsString;
} finally {
if (is != null) {
is.close();
}
}
}
public String convertInputStreamToString(InputStream stream, int length) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[length];
reader.read(buffer);
return new String(buffer);
}

Storing session cookie to maintain log in session

I've been trying to get this work for a while now. Im working on an app where the user signs in with a username and password which uses a httppost request to post to the server. i get the correct response, and during the post i store the session cookie that the server gives me. (I store it in a cookie store)
But when i try to click a link on the menu ( which does a second http post) after i logged in, the servers gives me a message saying that i am not logged in. But i send the cookie that i recieved in the first post to the server in the second post, yet the server does not recognize that i am logged in. To test this more easily i used the chrome plug in "Postman" which lets you post to websites easily. The only time it worked was when i log in to the website using chrome then use Postman to do the second post, which successfully gives me a response. however, when i use Postman to log in, then also use postman to attempt the second post , again, "Not logged in". Im guessing that the cookie is not being stored properly in the app. How could i go about fixing this? I read some stuff about storing the cookies in something called "Shared Preferences", is that possibly a fix? If so, what is it and how could i store the cookies there?
public static String executeHttpPost(String url, ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
LoginLayout.httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
CookieStore cookiestore = LoginLayout.httpClient.getCookieStore();
HttpResponse response = LoginLayout.httpClient.execute(request);
List<Cookie> cookies = LoginLayout.httpClient.getCookieStore().getCookies();
cookiestore.addCookie(cookie);
cookie = cookies.get(0);
cookieValue = "ASPSESSIONIDCQTCRACT=" + cookiestore.getCookies();
System.out.println("The cookie" + cookieValue);
List<Cookie> cookiess = cookiestore.getCookies();
cookiee = cookies.get(0);
Header[] headers = response.getAllHeaders();
System.out.println("length" + headers.length);
for (int i=0; i < headers.length; i++) {
Header h = headers[i];
System.out.println( "Header names: "+h.getName());
System.out.println( "Header Value: "+h.getValue());
}
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
// System.out.println( mCookie);
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
Here is the getter so i can access the cookie from the cookie store in the next activity
public static String getCookie(){
return cookiee.getName() +"="+cookiee.getValue();
}
Here is the second post where i try to retrieve the stored cookie, which it seems to do sucessfully, however the server doesnt recognize i am logged in
public static String executeHttpPost(String url, ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpPost request = new HttpPost(url);
request.setHeader("Cookie", LoginLayout.getCookie());
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
HttpResponse response = LoginLayout.httpClient.execute(request);
Header[] headers = response.getAllHeaders();
System.out.println("length" + headers.length);
for (int i=0; i < headers.length; i++) {
Header h = headers[i];
System.out.println( "Header names: "+h.getName());
System.out.println( "Header Value: "+h.getValue());
}
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
//System.out.println( mCookie);
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You have to make sure that your HttpClient is using the same HttpContext on each request.
The CookieStore is associated with the HttpContext so create a new instance of HttpContext will create a new CookieStore as well.
The best way I found is to create a static instance of HttpContext and use it on every request.
Below I added an part of a class I'm using in my apps:
public class ApiClient {
// Constants
private final static String TAG = "ApiClient";
private final static String API_URL = "your-url";
// Data
private static ApiClient mInstance;
private HttpClient mHttpClient;
private ThreadSafeClientConnManager mConnectionManager;
private HttpPost mPost;
/*
* we need it static because otherwise it will be recreated and the session
* will be lost
*/
private static HttpContext mHttpContext;
private HttpParams mParams;
private Context mContext;
public ApiClient(Context pContext) {
mParams = new BasicHttpParams();
mContext = pContext;
if (null == mHttpContext) {
CookieStore cookieStore = new BasicCookieStore();
mHttpContext = new BasicHttpContext();
mHttpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
}
ConnManagerParams.setMaxTotalConnections(mParams, 300);
HttpProtocolParams.setVersion(mParams, HttpVersion.HTTP_1_1);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
mConnectionManager = new ThreadSafeClientConnManager(mParams, schemeRegistry);
mHttpClient = new DefaultHttpClient(mConnectionManager, mParams);
}
public static ApiClient getInstance(Context pContext) {
if (null == mInstance) {
return (mInstance = new ApiClient(pContext));
} else {
return mInstance;
}
}
public void testPOST() {
List<NameValuePair> requestParams = new ArrayList<NameValuePair>();
requestParams.add(new BasicNameValuePair("param1", "value1"));
requestParams.add(new BasicNameValuePair("param2", "value2"));
mPost = new HttpPost(API_URL);
try {
mPost.setEntity(new UrlEncodedFormEntity(requestParams, HTTP.UTF_8));
HttpResponse responsePOST = mHttpClient.execute(mPost, mHttpContext);
HttpEntity resEntity = responsePOST.getEntity();
String result = EntityUtils.toString(resEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
To test it try setting the correct API_URL and
ApiClient api = ApiClient.getInstance(somContext);
api.testPOST();

JSON parsing issue with Gujarati font in Android text view

I have developed an application, that has text view for display some Gujarati text from the JSON URL and data stored in PHP MySQL server database.
So, problem with display Gujarati font:
My code of JSON http is here:
public class CustomHttpClient {
public static final int HTTP_TIMEOUT = 30 * 1000;
private static HttpClient mHttpClient;
private static HttpClient getHttpClient() {
if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
}
return mHttpClient;
}
public static String executeHttpPost(String url,ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));
// in = new BufferedReader(new InputStreamReader(is, "UTF-8"), 8000);
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e("log_tag", "Error converting result "+e.toString());
e.printStackTrace();
}
}
}
}
and main activity code here:
desc_about=(TextView)v.findViewById(R.id.textdesc);
Typeface tf=Typeface.createFromAsset(getActivity().getAssets(),"Shruti.ttf");
desc_about.setTypeface(tf);
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("temple_id","2"));
String response = null;
try {
response = CustomHttpClient.executeHttpPost(
url_temple,postParameters);
String result = response.toString();
try {
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++)
{
JSONObject json_data = jArray.getJSONObject(i);
about_temple=json_data.getString("about_text");
}
}
catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
try{
desc_about.setText(about_temple);
}
catch(Exception e){
Log.e("log_tag","Error in Display!" + e.toString());;
Toast.makeText(getActivity(), "error" + 2, 100).show();
}
}
catch (Exception e) {
Log.e("log_tag","Error in http connection!!" + e.toString());
Toast.makeText(getActivity(), "error" + 3, 100).show();
}
Try using utf-endcoding at the time of making JSON on php side and same way decode utf in android side. I solved it using this way in iOS app, Thanks
Try this solution
StringRequest stringRequest = new StringRequest(Request.Method.GET,"http://floming.com/shayri/guj_romanse.json", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String str = "";
try {
str = new String(response.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String decodedStr = Html.fromHtml(str).toString();

Upload file using HTTP Post multipart - 4Sharing API J2ME

I'm currently developing a J2ME app. I'm having problems with file uploading. I dont seem to know what part of my code is wrong. Here is my code:
public void UploadImage(long newFileId, String url, String bytes){
HttpConnection conn = null;
OutputStream os = null;
InputStream s = null;
StringBuffer responseString = new StringBuffer();
try
{
System.out.println(System.getProperty("HTTPClient.dontChunkRequests"));
conn.setRequestMethod(HttpConnection.POST);
conn = (HttpConnection)Connector.open(url);
conn.setRequestProperty("resumableFileId", ""+newFileId);
conn.setRequestProperty("resumableFirstByte", ""+0);
conn.setRequestProperty("FilePart", bytes);
// Read
s = conn.openInputStream();
int ch, i = 0, maxSize = 16384;
while(((ch = s.read())!= -1 ) & (i++ < maxSize))
{
responseString.append((char) ch);
}
conn.close();
System.out.println(responseString.toString());
String res = uploadFinishFile(newFileId, bytes);
if(res.length()>0)
System.out.println("File uploaded.");
else
System.out.println("Upload failed: "+res);
}
catch (Exception e)
{
System.out.println(e.toString());
}
}
This is the java code that im trying to convert to j2me:
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
MultipartEntity me = new MultipartEntity();
StringBody rfid = new StringBody("" + newFileId);
StringBody rfb = new StringBody("" + 0);
InputStreamBody isb = new InputStreamBody(new BufferedInputStream(new FileInputStream(f)), "FilePart");
me.addPart("resumableFileId", rfid);
me.addPart("resumableFirstByte", rfb);
me.addPart("FilePart", isb);
post.setEntity(me);
HttpResponse resp = client.execute(post);
HttpEntity resEnt = resp.getEntity();
String res = da.uploadFinishFile(login, password, newFileId, DigestUtils.md5Hex(new FileInputStream(f)));
if(res.isEmpty())
System.out.println("File uploaded.");
else
System.out.println("Upload failed: "+res);
} catch (Exception ex) {
System.out.println("Upload failed: "+ex.getMessage());
}
You are uploading the file passing the parameters as HTTP headers, instead of sending the image in the HTTP message body using multipart file upload, compatible with the code you're converting.
Take a look at HTTP Post multipart file upload in Java ME. You can use the HttpMultipartRequest class and change your code to:
Hashtable params = new Hashtable();
params.put("resumableFileId", "" + newFileId);
params.put("resumableFirstByte", "" + 0);
HttpMultipartRequest req = new HttpMultipartRequest(
url,
params,
"FilePart", "original_filename.png", "image/png", isb.getBytes()
);
byte[] response = req.send();

IOException: Internal Server Error when trying to consume rest service

I want to create a restful web service in java using jersey API and consume it in android application. I got this question on SO but it talks about java client whereas I have android client.
My service looks like this:
#Path("/no")
public class CheckNumber {
#POST
#Produces("application/json")
#Consumes("application/json")
public String getDetails(#PathParam("cNo") String cNo) {
String CardNo="";
try {
JSONObject jsonObj = new JSONObject(cNo);
CardNo=jsonObj.getString("CardNo");
} catch (ParseException e1) {
e1.printStackTrace();
}
//Do something
return "someValue";
}
}
Now comes the client side:
public class MainActivity extends Activity {
JSONObject json = new JSONObject();
String wsdl = "http://192.168.1.105:8080/restdemo/check/no/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RequestTask().execute("1234567890");
}
class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String add = "{\"CardNo\":\"" + uri[0] + "\"}";
HttpPost postMethod = new HttpPost(wsdl);
String responseString = null;
try {
postMethod.addHeader("Content-Type", "application/json");
HttpEntity entity = new StringEntity(add);
postMethod.setEntity(entity);
response = httpclient.execute(postMethod);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
I'm just starting with rest web services. I successfully created a sample rest service which consumes string and returns string and used this service in android app.
But when I try to pass json string using POST method. It's giving following errorin log:
java.io.IOException: Internal Server Error
at com.example.restclient.MainActivity$RequestTask.doInBackground(MainActivity.java:85)
where MainActivity.java:85 is throw new IOException(statusLine.getReasonPhrase()); which implies that statusLine.getStatusCode() is not returning HttpStatus.SC_OK. Instead it's returning status code = 500.
Any help appreciated.
It will be good to see the server side log to understand better.
Try creating the entity with UTF8 and set the content-type in the string entity rather than in the postMethod
StringEntity stringEntity = new StringEntity(myJsonDocStr, HTTP.UTF_8);
stringEntity.setContentType("application/json");
Try this code, It works for me
Boolean NetworkLostFlag = false;
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 10000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 12000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(strUrl");
try {
httppost.setEntity(new UrlEncodedFormEntity(new BasicNameValuePair(arg1, val1), "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
// do something useful
StringBuffer buffer = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = instream.read(b)) != -1;) {
buffer.append(new String(b, 0, n));
}
result = buffer.toString();
} catch (Exception e) {
NetworkLostFlag = true;
// TODO: handle exception
} finally {
instream.close();
}
}
} catch (Exception e) {
NetworkLostFlag = true;
e.printStackTrace();
}

Categories