Pushing message from Google App Engine to C2DM servers - android

I had already been able to
get the server authrization and saving it to datastore;
registering the phone to c2dm server and;
sending the id to the app server which save the application c2dm regeistration id to datastore.
Now I just want to implement a servlet that retrieves the server token no. and android application regirstration id from datastore and use them to push a message to phone.
This is the code for the servlet:
package com.visd.myfirstapp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
//import com.visd.myfirstapp.MessageUtil.CustomizedHostnameVerifier;
public class Visd extends HttpServlet {
private final static String AUTH = "authentication";
private static final String UPDATE_CLIENT_AUTH = "Update-Client-Auth";
public static final String PARAM_REGISTRATION_ID = "registration_id";
public static final String PARAM_DELAY_WHILE_IDLE = "delay_while_idle";
public static final String PARAM_COLLAPSE_KEY = "collapse_key";
private static final String UTF8 = "UTF-8";
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException
{
resp.setContentType("text/plain");
Entity appRegIdEntity = null;
Entity serverTokenEntity = null;
int RetCode = 0;
String message = "Congrats C2DM process completed";
Key appRegIdKEY = KeyFactory.createKey("c2dmreg","cr");
Key serverTokenKEY = KeyFactory.createKey("vToken", "tokenkn");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
String appRegId = null, serverToken = null, chk =null;
try {
appRegIdEntity = datastore.get(appRegIdKEY);
serverTokenEntity = datastore.get(serverTokenKEY);
serverToken = (String) serverTokenEntity.getProperty("token");
appRegId = (String) appRegIdEntity.getProperty("c2dmid");
RetCode = sendMessage(serverToken, appRegId, message);
} catch (EntityNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
chk = "Entered In Exception";
}
resp.getWriter().println("Return code :" + RetCode + "chk value :" + chk);
}
// Message Sending method
public static int sendMessage(String auth_token, String registrationId, String message) throws IOException
{
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder.append(PARAM_REGISTRATION_ID).append("=").append(registrationId);
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=").append("0");
postDataBuilder.append("&").append("data.payload").append("=").append(URLEncoder.encode(message, UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
URL url = new URL("https://android.clients.google.com/c2dm/send");
//HttpsURLConnection.setDefaultHostnameVerifier(new CustomizedHostnameVerifier());//commented as was causing error, i dont know why
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",Integer.toString(postData.length));
conn.setRequestProperty("Authorization", "GoogleLogin auth="+ auth_token);
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int responseCode = conn.getResponseCode();
return responseCode;
}
}
But the browser always shows the RetCode = 0 and Chk value = "Entered in Exception" i.e.It never sends the message to the android device, instead always enters in the exception. What wrong in the code i couldn't figure out..
please help.
Thank you.

This is how I finally solved, code help :-
public class C2dmsender {
public static String send(String regid, String appRegId, String mtype, String[] message) throws UnsupportedEncodingException
{
String serverToken = ""//give the sever token here;
data.append("registration_id=" + appRegId);//appRegId is the C2DM id of the device in which you want to push
// Collapse key is for grouping messages and only the last sent message
// with the same key going to be sent to the phone when the phone is
// ready to get the message if its not from the beginning
data.append("&collapse_key=test");
// Here is the message we sending, key1 can be changed to what you whant
// or if you whant to send more then one you can do (i think, not tested
// yet), Testing is the message here.
data.append("&data.key1=");
// If you whant the message to wait to the phone is not idle then set
// this parameter
// data.append("&delay_while_idle=1");
byte[] postData = data.toString().getBytes("UTF-8");
try {
// Send data
URL url = new URL("https://android.apis.google.com/c2dm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",
Integer.toString(postData.length));
conn.setRequestProperty("Authorization", "GoogleLogin auth="
+ serverToken);
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
Integer responseCode = conn.getResponseCode();
if (responseCode.equals(503)) {
// the server is temporarily unavailable
} else {
if (responseCode.equals(401)) {
// AUTH_TOKEN used to validate the sender is invalid
} else {
if (responseCode.equals(200)) {
// Check for updated token header
String updatedAuthToken = conn
.getHeaderField("Update-Client-Auth");
if (updatedAuthToken != null) {
serverToken = updatedAuthToken;
}
String responseLine = new BufferedReader(
new InputStreamReader(conn.getInputStream()))
.readLine();
}
}
} catch (Exception e) {
}
}
}

Related

login to website using httpulrconnection

I've got a server set up to accept email & password credentials and I want my app to login using HttpURLconnection. The connection part seems to be ok, since the response is alway 200, but I'm having trouble actually sending the data. I convert the json pair to string and send it through DataOutputStream. I read the response through InputStream.
My main problem is the response I read with InputStream is always the same (the html of the login page) even if the email&password are wrong, which has me thinking I'm not sending the data correctly.
You can take a look at my code:
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.JsonWriter;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.app.ProgressDialog;
import java.io.DataOutputStream;
import java.net.MalformedURLException;
import android.net.Uri;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.content.Intent;
import org.json.JSONObject;
import org.json.JSONStringer;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private EditText user;
private EditText pswrd;
private Button login;
private String email;
private String password;
private String HOST;
private String DEFAULT_IPADDRESS;
private String PREFERENCES_IPADDRESSSERVER;
private String PREFERENCES_TOKEN;
private Context ctx;
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private String sRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
user = (EditText) findViewById(R.id.Email);
pswrd = (EditText) findViewById(R.id.Password);
login = (Button) findViewById(R.id.button);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
email = user.getText().toString();
password = pswrd.getText().toString();
try {
//HttpURLConnection example = serverLogin(email, password);
new AsyncLogin().execute(email, password);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private class AsyncLogin extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
// Enter URL address
url = new URL("http://81.169.151.83/users/sign_in");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
try {
// Setup HttpURLConnection class to send and receive data
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
JSONObject request = new JSONObject();
try {
request.put("email", params[0]);
request.put("password", params[1]);
} catch (org.json.JSONException e) {
e.printStackTrace();
}
sRequest = request.toString();
// Open connection for sending data
conn.connect();
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(sRequest);
wr.flush();
wr.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return "exception";
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return "exception";
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
if (result.equalsIgnoreCase("true")) {
/* Here launching another activity when login successful. If you persist login state
use sharedPreferences of Android. and logout button to clear sharedPreferences.
*/
Toast.makeText(MainActivity.this, "GREAT SUCCESS", Toast.LENGTH_LONG).show();
/* Intent intent = new Intent(MainActivity.this,SuccessActivity.class);
startActivity(intent);
MainActivity.this.finish();*/
} else if (result.equalsIgnoreCase("false")) {
// If username and password does not match display a error message
Toast.makeText(MainActivity.this, "Invalid email or password", Toast.LENGTH_LONG).show();
} else if (result.equalsIgnoreCase("exception") || result.equalsIgnoreCase("unsuccessful")) {
Toast.makeText(MainActivity.this, "OOPs! Something went wrong. Connection Problem.", Toast.LENGTH_LONG).show();
}
}
}
Thanks
I would recommend you to try OKHTTP, check out their recipes, it is a lot simpler to do GET / POST requests in Android.
On a side note, I've checked out your website at http://81.169.151.83/users/sign_in and the parameters used for the login form is user[email] and user[password]. Not the email and password which you added above. There are also several other form fields such as authenticity_token which might be the cause.

how to post json data to the restful API in header to get json response android

I want to make connection to the api and post the string data to the api to get the json result but i dont know howit is done here is my code , can anyone tell me how to put json data in this url connection and pass it
package practise.c.practise;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class API extends AppCompatActivity {
String USERID;
String APIKEY;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_api);
Log.d("oncreate", "onCreate: ");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Log.d("threadrun", "onCreate: ");
URL url = new URL("https://api.api.com/v1");
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
String userCredentials = "2223:6c005hhhh1eggggf4447b59bfed";
String basicAuth = Base64.encodeToString(userCredentials.getBytes(),Base64.DEFAULT);
httpURLConnection.setRequestProperty ("Authorization","Basic" + basicAuth);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Accept-Language", "en");
int responseCode = httpURLConnection.getResponseCode();
Log.d("responsecode", "run: "+responseCode);
if(responseCode == 200){
InputStream inputStr = httpURLConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStr));
StringBuilder result = new StringBuilder();
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
Log.d("API:DATA", "run: "+result);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
}
Try the following code template. What you need is explained in comments within the code.
/**
* Created by sibidharan on 18/11/14.
* Sample class
*/
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.StringBody;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
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.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
/*
Usage of the class
Create all the necessary API Call methods you need.
And either use a Thread or AsyncTask to call the following.
JSONObject response = ApiUrlCalls.login("username", "passowrd");
After the response is obtained, check for status code like
if(response.getInt("status_code") == 200){
//TODO: code something
} else {
//TODO: code something
}
*/
public class ApiUrlCalls {
private String HOST = "https://domain/path/"; //This will be concated with the function needed. Ref:1
/*
Now utilizing the method is so simple. Lets consider a login function, which sends username and password.
See below for example.
*/
public static JSONObject login(String username, String password){
String functionCall = "login";
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("username", username)
.appendQueryParameter("password", password);
/*
The return calls the apiPost method for processing.
Make sure this should't happen in the UI thread, orelse, NetworkOnMainThread exception will be thrown.
*/
return apiPost(builder, functionCall);
}
/*
This method is the one which performs POST operation. If you need GET, just change it
in like Connection.setRequestMethod("GET")
*/
private static JSONObject apiPost(Uri.Builder builder, String function){
try {
int TIMEOUT = 15000;
JSONObject jsonObject = new JSONObject();
try {
URL url = null;
String response = "";
/*
Ref:1
As mentioned, here below, in case the function is "login",
url looks like https://domain/path/login
This is generally a rewrited form by .htaccess in server.
If you need knowledge on RESTful API in PHP, refer
http://stackoverflow.com/questions/34997738/creating-restful-api-what-kind-of-headers-should-be-put-out-before-the-response/35000332#35000332
I have answered how to create a RESTful API. It matches the above URL format, it also includes the .htaccess
*/
url = new URL(HOST + function);
HttpsURLConnection conn = null;
conn = (HttpsURLConnection) url.openConnection();
assert conn != null;
conn.setReadTimeout(TIMEOUT);
conn.setConnectTimeout(TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
String query = builder.build().getEncodedQuery();
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
int responseCode = conn.getResponseCode();
String responseMessage = conn.getResponseMessage();
jsonObject.put("status_code", responseCode);
jsonObject.put("status_message", responseMessage);
/*The if condition below will check if status code is greater than 400 and sets error status
even before trying to read content, because HttpUrlConnection classes will throw exceptions
for status codes 4xx and 5xx. You cannot read content for status codes 4xx and 5xx in HttpUrlConnection
classes.
*/
if (jsonObject.getInt("status_code") >= 400) {
jsonObject.put("status", "Error");
jsonObject.put("msg", "Something is not good. Try again later.");
return jsonObject;
}
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
//Log.d("RESP", response);
/*
After the actual payload is read as a string, it is time to change it into JSON.
Simply when it starts with "[" it should be a JSON array and when it starts with "{"
it is a JSONObject. That is what hapenning below.
*/
if(response.startsWith("[")) {
jsonObject.put("content", new JSONArray(response));
}
if(response.startsWith("{")){
jsonObject.put("content", new JSONObject(response));
}
} catch(UnknownHostException e) {
//No explanation needed :)
jsonObject.put("status", "UnknownHostException");
jsonObject.put("msg", "Check your internet connection");
} catch (SocketTimeoutException){
//This is when the connection timeouts. Timeouts can be modified by TIMEOUT variable above.
jsonObject.put("status", "Timeout");
jsonObject.put("msg", "Check your internet connection");
} catch (SSLPeerUnverifiedException se) {
//When an untrusted SSL Certificate is received, this happens. (Only for https.)
jsonObject.put("status", "SSLException");
jsonObject.put("msg", "Unable to establish secure connection.");
se.printStackTrace();
} catch (IOException e) {
//This generally happens when there is a trouble in connection
jsonObject.put("status", "IOException");
jsonObject.put("msg", "Check your internet connection");
e.printStackTrace();
} catch(FileNotFoundException e){
//There is no chance that this catch block will execute as we already checked for 4xx errors
jsonObject.put("status", "FileNotFoundException");
jsonObject.put("msg", "Some 4xx Error");
e.printStackTrace();
} catch (JSONException e){
//This happens when there is a troble reading the content, or some notice or warnings in content,
//which generally happens while we modify the server side files. Read the "msg", and it is clear now :)
jsonObject.put("status", "JSONException");
jsonObject.put("msg", "We are experiencing a glitch, try back in sometime.");
e.printStackTrace();
} return jsonObject;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
I just made changes in two lines of my code and my code started working
URL url = new URL("http://api.api.com/v1");// http instead of https
httpURLConnection.setRequestProperty ("Authorization","Basic " + basicAuth);//gave space after Basic

Inserting the data in to the local server from android Application

I have developed an application which uses GCM notifications, i have successfully registered the device with GCM, and retrieved regId, now i want to send this ID to my server.
i am using this code to send the regId:
package com.example.gcm;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import android.content.Context;
import android.util.Log;
public class ShareExternalServer {
public String shareRegIdWithAppServer(final Context context,
final String regId) {
String result = "";
Map<String, String> paramsMap = new HashMap<String, String>();
paramsMap.put("regId", regId);
try {
URL serverUrl = null;
try {
serverUrl = new URL(Config.APP_SERVER_URL);
} catch (MalformedURLException e) {
Log.e("AppUtil", "URL Connection Error: "
+ Config.APP_SERVER_URL, e);
result = "Invalid URL: " + Config.APP_SERVER_URL;
}
StringBuilder postBody = new StringBuilder();
Iterator<Entry<String, String>> iterator = paramsMap.entrySet()
.iterator();
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
postBody.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
postBody.append('&');
}
}
String body = postBody.toString();
byte[] bytes = body.getBytes();
HttpURLConnection httpCon = null;
try {
httpCon = (HttpURLConnection) serverUrl.openConnection();
httpCon.setDoOutput(true);
httpCon.setUseCaches(false);
httpCon.setFixedLengthStreamingMode(bytes.length);
httpCon.setRequestMethod("POST");
httpCon.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
OutputStream out = httpCon.getOutputStream();
out.write(bytes);
out.close();
int status = httpCon.getResponseCode();
if (status == 200) {
result = "RegId shared with Application Server. RegId: "
+ regId;
} else {
result = "Post new one1 Failure." + " Status: " + regId;
}
} finally {
if (httpCon != null) {
httpCon.disconnect();
}
}
} catch (IOException e) {
result = "Post Failure 33 . Error in sharing with App Server."+regId;
Log.e("AppUtil", "Error in sharing with App Server: " + e);
}
return result;
}
}

How to resolve android.os.networkonmainthreadexception

I am new to android and I am trying to read data from a server. I use a util and call that util like this
private void ParseSource(String Url){
String source = new Cls_SourceGrabber().grabSource(Url);
}
But I am getting a android.os.networkonmainthreadexception. How can I reduce that?
My SourceGrabber util:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
public class Cls_SourceGrabber {
private HttpGet mRequest;
private HttpClient mClient;
private BufferedReader mReader;
private StringBuffer mBuffer;
private String mNewLine;
public Cls_SourceGrabber() {
mRequest = new HttpGet();
InitializeClient();
mReader = null;
mBuffer = new StringBuffer(10000);
mNewLine = System.getProperty("line.separator");
}
private void InitializeClient() {
if (mClient == null || mClient.getConnectionManager() == null) {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 4500);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
// HttpConnectionParams.setTcpNoDelay(httpParameters, true);
mClient = new DefaultHttpClient(httpParameters);
}
}
/*
*Grab the full source
*/
public String grabSource(String url) {
mBuffer.setLength(0);
InitializeClient();
String source = "";
try {
mRequest.setURI(new URI(url));
HttpResponse response = mClient.execute(mRequest);
mReader = new BufferedReader(new InputStreamReader(response
.getEntity().getContent()));
String line = "";
while ((line = mReader.readLine()) != null) {
mBuffer.append(line);
mBuffer.append(mNewLine);
source = mBuffer.toString();
if (Thread.interrupted()) {
break;
}
}
} catch (ConnectTimeoutException e) {
source = "Connection Timed Out.";
} catch (java.net.UnknownHostException e) {
source = "No Internet Connection available!";
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
source = "Site Parsing Exception.";
} catch (ClientProtocolException e) {
source = "Protocol Exception.";
} catch (IOException e) {
source = "Server not responding.";
} catch (URISyntaxException e) {
source = "Wrong URL!";
} catch (Exception e) {
source = "Exception - " + e.toString() + " - "
+ e.getMessage();
e.printStackTrace();
} finally {
closeReader();
}
return source;
}
}
First of all, I would not recommend on using HTTPClient any more, since it is not supported any more from sdk version 23.
So, it will be better to migrate the network operations to URL Connection.
Now, android never allows network operations on Main thread since it will block the UI thread for a considerable time, hence may cause crash or bad user experience.
You can take a look on these docs : Doc 1
The better way to do Network operations is by creating an AsyncTask.
Just take care not to access any UI thread element in the doInBackground method. You can modify UI Thread elements on onPreExecute or onPostExecute Methods.
I have created a NetworkOps Util. You can take a look on that, whether it may be any use for you :
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.csehelper.variables.Constants;
import com.csehelper.variables.Keys;
import com.csehelper.variables.Url;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;
public class NetworkOps {
public final String EXCEPTION = "~Exception~";
/****************************
* Method to Grab Source
****************************/
public static String GrabSource(String URL) {
return PostData(URL, null);
}
/**
* *****************************************
* Method to Grab Source code from URL
* Posting Data
* *****************************************
*/
private static String PostData(String url, Uri.Builder uribuilder) {
String Source;
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setDoOutput(true);
urlConnection.setConnectTimeout(10000);
if(uribuilder != null) {
String query = uribuilder.build().getEncodedQuery();
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
}
urlConnection.connect();
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
String line;
StringBuilder builder = new StringBuilder();
InputStreamReader isr = new InputStreamReader(
urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
while ((line = reader.readLine()) != null) {
builder.append(line);
}
Source = builder.toString();
} else {
Source = EXCEPTION + "Server unreachable. Check network connection.";
}
} catch (SocketTimeoutException e) {
Source = EXCEPTION + "Connection timed out.";
} catch (java.net.UnknownHostException e) {
Source = EXCEPTION + Constants.EXCEPTION_NO_NET;
} catch (ArrayIndexOutOfBoundsException e) {
Source = EXCEPTION + "Server error";
} catch (ProtocolException e) {
Source = EXCEPTION + "Protocol error";
} catch (IOException e) {
Source = EXCEPTION + "Server unreachable. Check network connection.";
} catch (Exception e) {
Source = EXCEPTION + "Error:" + e.toString() + " - "
+ e.getMessage();
e.printStackTrace();
} finally {
if (urlConnection != null) urlConnection.disconnect();
}
return Source;
}
}
Call these Static Functions from AsyncTask:
/*********************************
* AsyncTask to GrabSource
********************************/
class AsyncTask_GrabSource extends AsyncTask<Void, Void, Void> {
String Source = null;
String url = "https://enigmatic-woodland-35608.herokuapp.com/pager.json";
#Override
protected void onPreExecute() {
//Runs on Main Thread. You can access your UI elements here.
}
#Override
protected Void doInBackground(Void... params) {
// Don't access any UI elements from this function
Source = NetworkOps.GrabSource(this.url);
return null;
}
#Override
protected void onPostExecute(Void result) {
if (Source != null) {
if (!Source.contains("~Exception~")) {
//Show Error Message or do whatever you want
} else {
//Do Whatever with your Grabbed Sourcecode.
// This function runs on UI Thread, so you can update UI elements here
}
}
}
You can also post data with the function PostData. In method doInBackground, add this:
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("key", "value")
.appendQueryParameter("key2", "value2");
Source = NetworkOps.PostData(getApplicationContext(), url, builder);

Android applications can't upload photos to the server

I want to do an App. It can realize to upload the phone picture to server. Now it can take the picture and save to the mobile phone. But it can not upload into server. How to deal with this? The server is using tomcat to setup.
Android upload code:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class uploadActivity extends Activity
{
private Button uploadbutton;
private String uploadFile = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Test.jpg";
private String srcPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Test.jpg";
private String actionUrl = "http://192.168.1.105:8080/ATestInternetCameraServlet/";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
uploadbutton=(Button)findViewById(R.id.button2);
uploadbutton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
uploadFile();
}
});
}
private void uploadFile()
{ String uploadUrl = "http://192.168.1.105:8080/ATestInternetCameraServlet/CameraServlet";
String end = "\r\n";
String twoHyphens = "--";
String boundary = "******";
try
{
URL url = new URL(uploadUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setUseCaches(false);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(httpURLConnection
.getOutputStream());
dos.writeBytes(twoHyphens + boundary + end);
dos
.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\""
+ srcPath.substring(srcPath.lastIndexOf("/") + 1)
+ "\"" + end);
dos.writeBytes(end);
FileInputStream fis = new FileInputStream(srcPath);
byte[] buffer = new byte[8192]; // 8k
int count = 0;
while ((count = fis.read(buffer)) != -1)
{
dos.write(buffer, 0, count);
}
fis.close();
dos.writeBytes(end);
dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
dos.flush();
InputStream is = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
String result = br.readLine();
Toast.makeText(this, result, Toast.LENGTH_LONG).show();//
dos.close();
is.close();
} catch (Exception e)
{
e.printStackTrace();
setTitle(e.getMessage());
}
}
}
The server code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class CameraServlet extends HttpServlet
{
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
try
{
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out2 = response.getWriter();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
String uploadPath = "d:\\cameraupload\\";
File file = new File(uploadPath);
if (!file.exists())
{
file.mkdir();
}
String filename = "";
InputStream is = null;
for (FileItem item : items)
{
if (item.isFormField())
{
if (item.getFieldName().equals("filename"))
{
if (!item.getString().equals(""))
filename = item.getString("UTF-8");
}
}
else if (item.getName() != null && !item.getName().equals(""))
{
filename = item.getName().substring(
item.getName().lastIndexOf("\\") + 1);
is = item.getInputStream(); // 得到上传文件的InputStream对象
}
}
filename = uploadPath + filename;
if (new File(filename).exists())
{
new File(filename).delete();
}
// Began to upload files
if (!filename.equals(""))
{
// use FileOutputStream to open the upload file in server
FileOutputStream fos2 = new FileOutputStream(filename);
byte[] buffer = new byte[8192];
int count = 0;
// Began to read the upload file in bytes,and input it to server's upload file output stream
while ((count = is.read(buffer)) > 0)
{
fos2.write(buffer, 0, count); // To write the byte stream server files
}
fos2.close(); // close FileOutputStream object
is.close(); // InputStream object
out2.println("file upload success!xii");
}
}
catch (Exception e)
{
}
}
}
Do you have any error tracing?? Our just happening nothing??
For using httpurlconnection, you need to change the policy at the beginning:
ThreadPolicy mThreadPolicy = new ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(mThreadPolicy);
Try this.
Isn't 192.168.1.105 an IP-adress on the local network? Are you sure it's reachable from your phone? Open your phone's browser and try to navigate to the URL, can you reach it?
At what end are you having problems with the upload? Client or server? If it's on the client, what error are you getting? Or is it silently failing? Have you tried to make a simple HTML form and do the upload from there? If that is working you know it's your Android code that is the problem?
Also, it hurts every time I see someone trying to implement file uploads on their own. I'm not saying that your code is wrong, but it's an awful lot of lines of code (thus more risk of errors) compared to if you'd use a 3rd party library to abstract away all of that code for you. A well known and popular library such as Android Asynchronous Http Client has good support for file uploads out of the box:
AsyncHttpClient client = new AsyncHttpClient();
String filename = "file.png";
File myFile = new File("/path/to/" + filename);
RequestParams params = new RequestParams();
try {
params.put("file", myFile);
params.put("filename", filename);
client.post("http://192.168.1.105:8080/ATestInternetCameraServlet/CameraServlet", params, responseHandler);
}
catch(FileNotFoundException e) {
// handle
}
Try this...add apache-mime4j-0.6.jar and httpmime-4.0.3.jar libs
File f=new File(exsistingFileName);
HttpClient http = new DefaultHttpClient();
HttpPost post = new HttpPost("http://192.168.1.105:8080/ATestInternetCameraServlet/CameraServlet");
MultipartEntity Mentity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
String url1=exsistingFileName;
String mime;
String extension = MimeTypeMap.getFileExtensionFromUrl(url1);
if (extension != ""&&extension!=null) {
MimeTypeMap mime1 = MimeTypeMap.getSingleton();
mime = mime1.getMimeTypeFromExtension(extension);
}
else
{
String ext = url1.substring((url1.lastIndexOf(".") + 1), url1.length());
MimeTypeMap mime1 = MimeTypeMap.getSingleton();
mime = mime1.getMimeTypeFromExtension(ext);
}
ContentBody cbFile;
if(mime!=null)
cbFile= new FileBody(f,mime);
else
cbFile=new FileBody(f);
Mentity.addPart("file",cbFile);
post.setEntity(Mentity);
HttpResponse response = null;
try {
response = http.execute(post);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
responseString = new BasicResponseHandler().
handleResponse(response);
} catch (HttpResponseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}

Categories

Resources