I was following this tutorial to upload images with android: here
After the line conn.setRequestProperty("uploaded_file", fileName); in function uploadFile(String sourceFileUri) I added further lines with conn.setRequestProperty("title", "example"); conn.setRequestProperty("name", "simple_image"); but in the php file I am not receiving these strings with $_POST or $_GET only the image is uploaded.
Is this tutorial here only for uploading images?
I would like to send with the image some other data too. How could I do this?
Thank you
Yes that tutorial is for uploading a single file only.If you want to send some other data(may be some strings) along with your image, then you can use MultipartEntityBuilder.However to use this you need to download the jars from the Apache HttpComponents site and add them to project and path(just add the httpclient jar to your libs folder).
Now for uploading an image along with some string data you can use (may be inside doInBackground of your AsynTask)
File file = new File("yourImagePath");
String urlString = "http://yoursite.com";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
/* setting a HttpMultipartMode */
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
/* adding an image part */
FileBody bin1 = new FileBody(file);
builder.addPart("uploadedfile1", bin1);
builder.addPart("user", new StringBody("Some String",ContentType.TEXT_PLAIN));//adding a string
HttpEntity reqEntity = builder.build();
post.setEntity(reqEntity);
HttpEntity resultEntity = httpResponse.getEntity();
String result = EntityUtils.toString(resultEntity);
P.S : I assumed you are using AsyncTask for uploading process and that's the reason i said to use this code inside doInBackground of your AsyncTask.
You can use MultipartEntity too.Follow this tutorial which describes how to upload multiple images along with some other string data using MultipartEntity.However there's not much difference in the implementation of MultipartEntity and MultipartEntityBuilder.Try yourself to learn both.Hope these info help you.
Related
I would like the users of my Android app to be able to send zip files to my server using http. The use case I am imagining looks like this:
The user sends a zip file and a String containing a password using a HttpClient and HttpPost (as described here) to my server.
By logging in to www.example.com/my_app with existing password, users can download the files that the people have sent to my server under the given password.
I don't understand how to do the second step. What code do I need to write on my website to receive files that the Android users have been sending? I have a shared server under my hosting plan and a simple website.
You first need to modify the upload code(Since file upload is treated as multipart data).
Here is the modified upload code--
String url = "http://localhost/upload.php";
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
"file.txt");
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
Part[] parts = new Part[1];
parts[0] = new FilePart("fileToUpload", file);
MultipartEntity reqEntity = new MultipartEntity(parts);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true); // Send in multiple parts if needed
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
} catch (Exception e) {
e.printStackTrace();
}
Here I have used the fileToUpload as the parameter key for uploaded file. On server code you can use the same key for your $_FILES["fileToUpload"].
Here is the simplest PHP code to accept the uploaded data from above android code--
<?php
$target_dir = "/Users/chauhan/Desktop/uploads/";
$target_file = $target_dir . basename("abc.txt");
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
?>
I have huge json data to upload on server, but when I upload using HttpPost getting SocketTimeout Exception, while I changed timeout to 25000 and more.
Does anyone has solution for it?
Does MultiPartEntity will help me in this case ?
If yes then how to send json data on server using MultiPartEntity?
Yes MultiPartEntry from Apache MIME can help you in this case. It is sometimes used for uploading images with some contextual data in multiple parts.
For sending Json you can do something like this
You will have to use MultipartEntityBuilder to create MultipartEntity object.
//use builder as MultipartEntity is deprecated
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
String yourJsonString = yourJSONObject.toString();
builder.addPart("key_to_yourJsonString", yourJsonString ); //set your Json String
HttpEntity entity = builder.build(); //create entity
httppost.setEntity(entity);
response = httpClient.execute(httppost);
you would require httpclient.jar, httpcore.jar, httpmime.jar, httpclient.jar, commons-codec.jar and commons-logging.jar to be in classpath.
Refer the below links for more info on this.
bethecoder MultipartEntityDeprecated
I'd like create a method for uploading image from Android to a REST Server through POST method.
Is the following code I wrote right?
Thank you in advance!
my code:
//Creating multi part http connection in post mode
HttpPost request = new HttpPost("url-to-my-server");
//Server header specs
request.setHeader("Accept","application/json");
request.setHeader("content-type","multipart/form-data");
request.setHeader("username",username);
request.setHeader("usertoken",token);
//Create entity parts
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addTextBody("param1","par1", ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("param2","par2", ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("param3","par3", ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("param4","par4", ContentType.TEXT_PLAIN);
//Add image
File fileImg = new File(picName);
multipartEntity.addBinaryBody("image",fileImg,ContentType.create("image/jpeg"),picName);
request.setEntity(multipartEntity.build());
httpclient.execute(request, retFunc);
I have a method to send image and text as a HttpPost using MultipartEntity content type. Everything works great with English symbols, but for unicode symbols (for example Cyrliics) it sends only ???. So, I'm wondering, how to set UTF-8 encoding for MultipartEntity correctly, since I've tried several sulutions, suggested on SO, but none of them worked.
Here what I have already:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
MultipartEntityBuilder mpEntity = MultipartEntityBuilder.create();
mpEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mpEntity.setCharset(Consts.UTF_8);
mpEntity.addPart("image", new FileBody(new File(attachmentUri), ContentType.APPLICATION_OCTET_STREAM));
ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
StringBody stringBody = new StringBody(mMessage, contentType);
mpEntity.addPart("message", stringBody);
final HttpEntity fileBody = mpEntity.build();
httpPost.setEntity(fileBody);
HttpResponse httpResponse = httpclient.execute(httpPost);
UPD
I tried to use InputStream as per #Donaudampfschifffreizeitfahrt suggestion. Now I'm getting ��� characters.
InputStream stream = new ByteArrayInputStream(mMessage.getBytes(Charset.forName("UTF-8")));
mpEntity.addBinaryBody("message", stream);
Also tried:
mpEntity.addBinaryBody("message", mMessage.getBytes(Charset.forName("UTF-8")));
I solved it a different way, using:
builder.addTextBody(key, שלום, ContentType.TEXT_PLAIN.withCharset("UTF-8"));
You can use below line for add part in multipart entity
entity.addPart("Data", new StringBody(data,Charset.forName("UTF-8")));
to send unicode in request.
To the ones who stuck with this issue, this is how I resolved it:
I investigated apache http components libraries source code and found following:
org.apache.http.entity.mime.HttpMultipart::doWriteTo()
case BROWSER_COMPATIBLE:
// Only write Content-Disposition
// Use content charset
final MinimalField cd = part.getHeader().getField(MIME.CONTENT_DISPOSITION);
writeField(cd, this.charset, out);
final String filename = part.getBody().getFilename();
if (filename != null) {
final MinimalField ct = part.getHeader().getField(MIME.CONTENT_TYPE);
writeField(ct, this.charset, out);
}
break;
So, seems like it is some kind of bug / feature in apache lib, which only allowes to add Content-type header to one part of MultipartEntity, if this part has filename not null. So I modified my code as:
Charset utf8 = Charset.forName("utf-8");
ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), utf8);
ContentBody body = new ByteArrayBody(mMessage.getBytes(), contentType, "filename");
mpEntity.addPart("message", body);
And Content-type header appeared for string part, and symbols are now encoded and decoded correctly.
I have an app on GAE at: http://1.myawesomecity.appspot.com/
FIXED:
HttpPost post = new HttpPost("http://1.myawesomecity.appspot.com/");
http_client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
String result = EntityUtils.toString( http_client.execute(post).getEntity(), "UTF-8");
String actualURL = result.substring(result.indexOf("http://"), result.indexOf("\" method"));
Log.w("asdf", "url " + actualURL );
post = new HttpPost(actualURL);
http_client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
String mime_type = "image/png";
File file = new File( filename ); //context.getFilesDir(),
entity.addPart( "myFile", new FileBody( file, mime_type));
post.setEntity( entity );
String res = EntityUtils.toString( http_client.execute(post).getEntity(), "UTF-8");
Log.w("asdf", res);
The above grabs the ACTUAL upload URL from the GAE server, and passes in the file as dictated by the CORRECT answer below.
Old Question:
As you can see, if you choose a file and hit submit, it will 404, but the file actually does get stored (as long as it is not too big, < 100kb). Don't type in anything in the first text field.
Now, putting aside how this particular app is barely functional, I'm trying to upload a file from Android onto this server.
The site's upload script uses blobstore, and the file field's name is "myFile".
Now in my Android app, I have:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(<my app's url>);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("myFile", <path to a file selected by user> ) );
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpclient.execute(httppost);
This throws an exception.
How is this any different from me going to my site through a browser, choosing a file, and hitting submit? Why does going through a browser actually go through with uploading the file, when the Android code does not?
I know that my filepath is valid. Is there something I'm doing wrong? or is clicking on "submit" from a browser different from executing a httpclient from Android?
Uploading file to a blobstore on GAE is a two step process:
first you need to get a proper URL where to POST your data, usually people use something like "/bloburl" handler for that purpose
when you have blob upload URL, you use it in your request.
the file you send does not go as NameValuePair, it's supposed to go as a MultiPartEntity.
here's the code that works (you'll need apache http library for MultiPartEntry support):
DefaultHttpClient http_client = new DefaultHttpClient();
HttpGet http_get = new HttpGet(Config.BASE_URL + "bloburl");
HttpResponse response = http_client.execute(http_get);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String first_line = reader.readLine();
Log.w(TAG, "blob_url: " + first_line);
HttpPost post = new HttpPost(first_line);
http_client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
mime_type = "application/zip";
File file = new File( context.getFilesDir(), filename );
entity.addPart( "file", new FileBody( file, mime_type));
post.setEntity( entity );
String result = EntityUtils.toString( http_client.execute(post).getEntity(), "UTF-8");
Log.i(TAG, result);