Upload image to server efficiently in Android - java

I have an app that needs to send an image to a server. Right now I'm doing it like this:
//We have a variable "image" that is the Bitmap that we want to send
File imagesFolder = new File(getCacheDir(), "images");
File file = null;
try {
if(imagesFolder.exists() || imagesFolder.mkdirs()) {
file = new File(imagesFolder, "input.jpg");
FileOutputStream stream = new FileOutputStream(file);
//checkWifiOnAndConnected returns true if wifi is on and false if mobile data is being used
image.compress(Bitmap.CompressFormat.JPEG, checkWifiOnAndConnected() ? 90 : 80, stream);
stream.flush();
stream.close();
}
} catch (IOException e) {
Log.d("Error", "IOException while trying to write file for sharing: " + e.getMessage());
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addPart("file", new FileBody(file));
HttpEntity entity = builder.build();
URL url = new URL(serverUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(40000);
conn.setConnectTimeout(40000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(entity.getContentLength());
conn.addRequestProperty(entity.getContentType().getName(), entity.getContentType().getValue());
OutputStream os = conn.getOutputStream();
entity.writeTo(os);
os.close();
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK)
Log.e("UPLOAD", "HTTP 200 OK.");
It works, but it's kinda slow, specially when using mobile data (obviously). And I would like to know if there's a more efficient and faster way to send this image.

Related

Upload File Using HTTP Post - Java

I have this current code. The file is in memory on the InputStream in or in test.pdf. I would prefer to only keep in-memory.
FileOutputStream fos = new FileOutputStream(new File("test.pdf"));
// Read file
InputStream in = url.openStream();
while((bufferLength = in.read(buffer)) != -1) {
fos.write(buffer, 0, bufferLength);
}
fos.flush();
// Close connections
fos.close();
in.close();
System.out.println("GOT DOCUMENT");
String submitURl = "https://someURL/submit";
// Send data
HttpURLConnection conn = (HttpURLConnection) new URL(submitURl).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestProperty("Content-Type","multipart/form-data");
conn.setRequestProperty("User-Agent", "Test Agent");
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.flush();
How do I post this file to the /submit URL. What am I missing here?

HttpURLConnection: resulting json-code suggests page doesnt exist (404), even when url is correct

I am trying to get data from an MySQL database using a php-file. My java code is as follows:
HttpURLConnection conn = null;
URL url = null;
try {
url = new URL(getURL);
System.out.println(getURL);
conn = (HttpURLConnection)url.openConnection();
//conn.setReadTimeout(READ_TIMEOUT);
//conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder();
builder.appendQueryParameter("user", USER);
builder.appendQueryParameter("pass", PASS);
builder.appendQueryParameter("server", SERVER);
builder.appendQueryParameter("db", DB);
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
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));
result = reader.readLine();
return(result);
}else{
return("unsuccessful");
}
When I go to my url (hidden in the variable getURL) using a browser, I see string of json on my screen, just as it should. However, when I output the contents of the reader (above code only takes the first line, but by adapting the code I can, of course, output more) it shows the html-code for a website displaying a 404 - Page does not exist message.
Anyone has any idea what goes wrong? Yes, I did check for typo's.
Okay, I have no clue what happened, as I didn't change anything. But all of the sudden it started working?!?
Must have been something server-side I guess...
Thanks for the input and sharing your thoughts!

Http request - already connected

Basically I've been using these particular lines of code for quite some time and never had problems with it. Nothing's been touched but now I'm getting
IllegalStateException - Already connected
exactly after I set conn.setUsesCaches(false)
public void PutImageToS3(String signedUrl, Bitmap image) throws WampNetworkException, IOException {
URL url = new URL(signedUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getDoOutput();
conn.setUseCaches(false);
conn.setRequestMethod("PUT");
conn.addRequestProperty("Content-Type", "image/jpeg");
conn.addRequestProperty("Connection", "close");
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
image.compress(Bitmap.CompressFormat.JPEG, 100, out);
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Failed to upload image to S3: "
+ conn.getResponseCode() + conn.getResponseMessage() + "\r\n");
}
out.flush();
out.close();
conn.disconnect();
}
Write this code in try-finally block and then try
public void PutImageToS3(String signedUrl, Bitmap image) throws WampNetworkException, IOException {
try{
URL url = new URL(signedUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getDoOutput();
conn.setUseCaches(false);
conn.setRequestMethod("PUT");
conn.addRequestProperty("Content-Type", "image/jpeg");
conn.addRequestProperty("Connection", "close");
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
image.compress(Bitmap.CompressFormat.JPEG, 100, out);
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Failed to upload image to S3: "
+ conn.getResponseCode() + conn.getResponseMessage() + "\r\n");
}
}
finally{
out.flush();
out.close();
conn.disconnect();
}
}
You need to write the request before getting the response code.
Move the close() before getResponseCode(), and remove the redundant flush().
NB Why are you calling getDoOutput() and ignoring the result?
Amazing solution has been found! There was a problem with the router today so uploading is hell. Once switched to internet from provider it worked like a charm :) GG!

Streaming Google Speech api

currently I can recognize speech to text using google's speech api. Now that I have this, I was just wondering if there is a way I can stream the response of transcribed text and give it more text to transcribe at the same time. In other words I want to speak into the microphone, and as I speak I want a response from the google servers. The code I am using currently:
System.out.println("openning connection");
HttpsURLConnection httpConn = null;
ByteBuffer buff = ByteBuffer.wrap(data);
byte[] destdata = new byte[2048];
int resCode = -1;
OutputStream out = null;
try {
URL url = new URL(urlStr);
URLConnection urlConn = url.openConnection();
if (!(urlConn instanceof HttpsURLConnection)) {
throw new IOException ("URL must be HTTPS");
}
httpConn = (HttpsURLConnection)urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("User-Agent", USER_AGENT);
httpConn.setDoOutput(true);
httpConn.setRequestProperty("AcceptEncoding", "gzip,deflate,sdch");
httpConn.setChunkedStreamingMode(0); //TransferType: chunked
httpConn.setRequestProperty("Content-Type", "audio/l16; rate=" + sampleRate);
// this opens a connection, then sends POST & headers.
out = httpConn.getOutputStream();
//beyond 15 sec duration just simply writing the file
// does not seem to work. So buffer it and delay to simulate
// bufferd microphone delivering stream of speech
// re: net.http.ChunkedOutputStream.java
while(buff.remaining() >= destdata.length){
buff.get(destdata);
out.write(destdata);
};
byte[] lastr = new byte[buff.remaining()];
buff.get(lastr, 0, lastr.length);
out.write(lastr);
out.close();
resCode = httpConn.getResponseCode();
if(resCode >= HttpURLConnection.HTTP_UNAUTHORIZED){//Stops here if Google doesn't like us/
System.out.println("unauthorized");
throw new HTTPException(HttpURLConnection.HTTP_UNAUTHORIZED);//Throws
}
String line;//Each line that is read back from Google.
BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
while ((line = br.readLine( )) != null) {
System.out.println(line);
if(line.length()>19 && resCode > 100 && resCode < HttpURLConnection.HTTP_UNAUTHORIZED){
GoogleResponse gr = new GoogleResponse();
parseResponse(line, gr);
fireResponseEvent(gr);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {httpConn.disconnect();}
Thanks for any help.

Getting 411 response code while getting JSON Response

In my application, I am trying get the response using POST request. The response server is sending me in Json format. But after adding the properties, it is returning me the response code as 411 (i.e issue with content length).
I have already added the content length. Then where is the issue i am not getting. Here is my code:
String url = "https://xxx:8243/people/v3";
STRURL = url + HttpComm.getConnectionString().trim();
StringBuffer postData = new StringBuffer();
HttpConnection httpConnection = null;
try {
httpConnection = (HttpConnection) Connector.open(STRURL);
} catch (IOException e1) {
e1.printStackTrace();
};
try {
httpConnection.setRequestMethod("POST");
postData.append("?username="+user);
postData.append("&password="+password);
String encodedData = postData.toString();
byte[] postDataByte = postData.toString().getBytes("UTF-8");
httpConnection.setRequestProperty("Authorization", "bearer"+"ZWOu3HL4vwaOLrFAuEFqsxNQf6ka");
httpConnection.setRequestProperty("Content-Type","application/json");
httpConnection.setRequestProperty("Content-Length", String.valueOf(postDataByte.length));
OutputStream out = httpConnection.openOutputStream();
DataOutputStream dos = new DataOutputStream(out);
out.write(postData.toString().getBytes());
out.flush();
int statusCode = httpConnection.getResponseCode();
Logger.out("HttpComm", "status code::::::: "+statusCode);
if (statusCode != HttpConnection.HTTP_OK)
{
}
Updated Code :
HttpConnection httpConnection = null;
try {
httpConnection = (HttpConnection) Connector.open(STRURL);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
};
try {
httpConnection.setRequestMethod("POST");
URLEncodedPostData postData = new URLEncodedPostData("UTF-8", false);
postData.append("username", user);
postData.append("password", password);
byte[] postDataByte = postData.getBytes();
httpConnection.setRequestProperty("Authorization", "bearer"+"ZWOu3HL4vwaOLrFAuEFqsxNQf6ka");
httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Content-Length", String.valueOf(postDataByte.length));
OutputStream out = httpConnection.openOutputStream();
out.write(postDataByte);
out.flush();
int statusCode = httpConnection.getResponseCode();
Logger.out("HttpComm", "status code::::::: "+statusCode);
There are a few things that don't look quite right here. I would recommend trying this:
httpConnection.setRequestMethod("POST");
URLEncodedPostData postData = new URLEncodedPostData("UTF-8", false);
postData.append("username", user);
postData.append("password", password);
byte[] postDataByte = postData.getBytes();
httpConnection.setRequestProperty("Authorization", "bearer"+"ZWOu3HL4vwaOLrFAuEFqsxNQf6ka");
httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Content-Length", String.valueOf(postDataByte.length));
OutputStream out = httpConnection.openOutputStream();
DataOutputStream dos = new DataOutputStream(out);
out.write(postDataByte);
out.flush();
int statusCode = httpConnection.getResponseCode();
Logger.out("HttpComm", "status code::::::: "+statusCode);
if (statusCode != HttpConnection.HTTP_OK)
What I changed:
As #samlewis said, the code was creating a variable to hold the post data bytes, but then was not using it when it called out.write().
The code set the content type to JSON, but it was not sending JSON. The request was simply two parameters. The response may be JSON, but you don't specify that in the request's Content-Type parameter.
The username/password parameters were encoded just using strings. Normally, it's best to use the URLEncodedPostData class to hold your POST parameters.
If you are going to use strings, I think it was still incorrect to add a ? to the front of the username parameter. If you want to encode parameters in a GET URL, then you use https://xxx:8243/people/v3?username=user&password=password. But, this code was using POST, not GET.
There was also an unused encodedData variable.

Categories

Resources