Android Httpclient File Upload Data Corruption And Timeout Issues
Solution 1:
See My Code of Image Uploader and it worked great for me This class Uploads a file to the server plus in the end read the XML reply also. Filter the code as per your requirement.. It worked pretty smooth for me
package com.classifieds;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
publicclassUploader
{
privateStringTag="UPLOADER";
private String urlString ;//= "YOUR_ONLINE_PHP";
HttpURLConnection conn;
String exsistingFileName ;
privatevoiduploadImageData(String existingFileName , String urlString)
{
StringlineEnd="\r\n";
StringtwoHyphens="--";
Stringboundary="*****";
try {
// ------------------ CLIENT REQUEST
Log.e(Tag, "Inside second Method");
FileInputStreamfileInputStream=newFileInputStream(newFile(
exsistingFileName));
// open a URL connection to the ServletURLurl=newURL(urlString);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
// Allow Inputs
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
// Don't use a cached copy.
conn.setUseCaches(false);
// Use a post method.
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStreamdos=newDataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos
.writeBytes("Content-Disposition: post-data; name=uploadedfile;filename="
+ exsistingFileName + "" + lineEnd);
dos.writeBytes(lineEnd);
Log.v(Tag, "Headers are written");
// create a buffer of maximum sizeintbytesAvailable= fileInputStream.available();
intmaxBufferSize=1000;
// int bufferSize = Math.min(bytesAvailable, maxBufferSize);byte[] buffer = newbyte[bytesAvailable];
// read file and write it into form...intbytesRead= fileInputStream.read(buffer, 0, bytesAvailable);
while (bytesRead > 0) {
dos.write(buffer, 0, bytesAvailable);
bytesAvailable = fileInputStream.available();
bytesAvailable = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// close streams
Log.v(Tag, "File is written");
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
Log.e(Tag, "error: " + ex.getMessage(), ex);
}
catch (IOException ioe) {
Log.e(Tag, "error: " + ioe.getMessage(), ioe);
}
SAXParserFactoryspf= SAXParserFactory.newInstance();
SAXParsersp=null;
try {
sp = spf.newSAXParser();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Get the XMLReader of the SAXParser we created.XMLReaderxr=null;
try {
xr = sp.getXMLReader();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Create a new ContentHandler and apply it to the XML-ReaderMyExampleHandler1myExampleHandler=newMyExampleHandler1();
xr.setContentHandler(myExampleHandler);
// Parse the xml-data from our URL. try {
xr.parse(newInputSource(conn.getInputStream()));
//xr.parse(new InputSource(new java.io.FileInputStream(new java.io.File("login.xml"))));
} catch (MalformedURLException e) {
Log.d("Net Disconnected", "NetDisconeeted");
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
Log.d("Net Disconnected", "NetDisconeeted");
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
Log.d("Net Disconnected", "NetDisconeeted");
// TODO Auto-generated catch block
e.printStackTrace();
}
// Parsing has finished.
}
publicUploader(String existingFileName, boolean isImageUploading , String urlString ) {
this.exsistingFileName = existingFileName;
this.urlString = urlString;
}
classMyExampleHandler1extendsDefaultHandler
{
// ===========================================================// Methods// ===========================================================@OverridepublicvoidstartDocument()throws SAXException {
}
@OverridepublicvoidendDocument()throws SAXException {
// Nothing to do
}
@OverridepublicvoidstartElement(String namespaceURI, String localName,
String qName, Attributes atts)throws SAXException {
}
/** Gets be called on closing tags like:
* </tag> */@OverridepublicvoidendElement(String namespaceURI, String localName, String qName)throws SAXException {
}
/** Gets be called on the following structure:
* <tag>characters</tag> */@Overridepublicvoidcharacters(char ch[], int start, int length) {
}
}
}
Solution 2:
I had the same corruption problem on 80% of my uploaded files. Emulator didn't fail to upload though. Corrupted files were 1k larger that original ones. Then I set the buffer of the output stream to 1 byte and it began to work with no problem. Finally I let it be 8 bytes and haven't had no more corruption problems. A buffer of about 80 or 50, I can't remember, also failed. Don't understand what the problem is but I'm happy it is working this way. This page was so inspiring thanks.
Solution 3:
ok. spent 2 days on testing this issue and found out following: when using tcpdump on android it comes that the data wasn't corrupt, BUT the tcp packet size was 1516, which is very strange, cause the normal ethernet packet size is 1500 and everything more than 1516 is way too big. i manually changed the MTU to 576 (i believe it is the standard for ppp, which 3G actually is) and it works perfect! 150 of 150 images were uploaded normally!
this doesn't solve the actual problem, though, cause it's impossible to change mtu on non-rooted devices i believe, and you have to change it every time you reboot the device (or every time you bring up the interface - not sure about it, cause couldn't find the way of getting MTU value via ifconfig). but at least i know where the problem is. setting http chunk size to a smaller value (tried 300 bytes) didn't affect it (i believe it's because the http headers are way too big themselves)... so... so nothing =)
will try to post it to android-developer group on google, but their moderation is way too slow... we'll see...
Post a Comment for "Android Httpclient File Upload Data Corruption And Timeout Issues"