I have a class that implements a multipart file upload. The code works on every java client I've tried it on but does not work on Android, *and* it's the only HTTP request code in my Android app that doesn't play nice with my back end service. I've looked through the posts to see if other are having similar issues but so far have only found posts like this http://groups.google.com/group/android-developers/msg/c4b0270153d194d9 , which are nearly the same as mine. T The symtoms I'm seeing are that the connection responseCode is "-1" & no entries show up in the Apache access or error logs. It seems as if the request is never making it off of the android platform. The code gets right through the connection writes in the debugger with no errors, but hangs on the connection read, times out and then returns with -1. Behavior is same for real phone and emulator. As I mentioned, this code is in use elsewhere and works fine.
Does anyone know of any gotchas one needs to look out for when posting a multipart file in Android? Anything about doing a POST or a POST w/ data on Android? I'm including the code/class below so you can see what I'm up to. package com.abaqus.georecorder; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.util.Log; public class GeoPictureUploader { static String serviceDomain = "http://staging.abaqus.net"; static String postUrl = serviceDomain + "/geo/upl/wupload/ pictures"; static String CRLF = "\r\n"; static String twoHyphens = "--"; static String boundary = "*****mgd*****"; private static String TAG = "PictureUploader"; private String pictureFileName = null; private String name = null; private String password = null; private DataOutputStream dataStream = null; enum ReturnCode { noPicture, unknown, http201, http400, http401, http403, http404, http500}; public GeoPictureUploader(String name, String password) { this.name = name; this.password = password; } public static void setServiceDomain(String domainName) { serviceDomain = domainName; } public static String getServiceDomain() { return serviceDomain; } public ReturnCode uploadPicture(String pictureFileName) { this.pictureFileName = pictureFileName; File uploadFile = new File(pictureFileName); if (uploadFile.exists()) try { FileInputStream fileInputStream = new FileInputStream (uploadFile); URL connectURL = new URL(postUrl); HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("User-Agent", "myGeoDiary- V1"); conn.setRequestProperty("Connection","Keep-Alive"); conn.setRequestProperty("Content-Type","multipart/form- data;boundary="+boundary); conn.connect(); dataStream = new DataOutputStream(conn.getOutputStream ()); writeFormField("login", name); writeFormField("password", password); writeFormField("fileName", "anyName.jpg"); // this field not used, but needed for validator writeFormField("data", "none"); // again, that damned spring validator writeFileField("photo1", pictureFileName, "image/jpg", fileInputStream); // final closing boundary line dataStream.writeBytes(twoHyphens + boundary + twoHyphens + CRLF); fileInputStream.close(); dataStream.flush(); dataStream.close(); dataStream = null; String response = getResponse(conn); Log.e(TAG, "GeoPictureUploader.uploadPicture got response: " + response); if (response.contains("uploaded successfully")) { Log.v(TAG, "ReturnCode: upload successful"); return ReturnCode.http201; } else { // 401 is only way to fail on this call Log.v(TAG, "ReturnCode: 401 upload *un*successful"); return ReturnCode.http401; } } catch (MalformedURLException mue) { Log.e(TAG, "error: " + mue.getMessage(), mue); System.out.println("GeoPictureUploader.uploadPicture: Malformed URL: " + mue.getMessage()); return ReturnCode.http400; } catch (IOException ioe) { Log.e(TAG, "error: " + ioe.getMessage(), ioe); System.out.println("GeoPictureUploader.uploadPicture: IOE: " + ioe.getMessage()); return ReturnCode.http500; } catch (Exception e) { Log.e(TAG, "error: " + e.getMessage(), e); System.out.println("GeoPictureUploader.uploadPicture: unknown: " + e.getMessage()); return ReturnCode.unknown; } else { Log.v(TAG, "ReturnCode: noPicture"); return ReturnCode.noPicture; } } /** * @param conn * @return */ private String getResponse(HttpURLConnection conn) { try { // try doing this in one read DataInputStream dis = new DataInputStream (conn.getInputStream()); byte[] data = new byte[1024]; int len = dis.read(data, 0, 1024); int responseCode = conn.getResponseCode(); return new String(data, 0, len); } catch(Exception e) { System.out.println("GeoPictureUploader: biffed it getting HTTPResponse"); //Log.e(TAG, "GeoPictureUploader: biffed it getting HTTPResponse"); } return ""; } /** original response getter... */ private String getResponseOrig(HttpURLConnection conn) { try { // scoop up the reply from the server InputStream is = conn.getInputStream(); int ch; StringBuffer sb = new StringBuffer(); while( ( ch = is.read() ) != -1 ) { sb.append( (char)ch ); } return sb.toString(); // TODO Auto-generated method stub } catch(Exception e) { System.out.println("GeoPictureUploader: biffed it getting HTTPResponse"); //Log.e(TAG, "GeoPictureUploader: biffed it getting HTTPResponse"); } return ""; } /** * write one form field to dataSream * @param fieldName * @param fieldValue */ private void writeFormField(String fieldName, String fieldValue) { try { dataStream.writeBytes(twoHyphens + boundary + CRLF); dataStream.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + CRLF); dataStream.writeBytes(CRLF); dataStream.writeBytes(fieldValue); dataStream.writeBytes(CRLF); } catch(Exception e) { System.out.println("GeoPictureUploader.writeFormField: got: " + e.getMessage()); //Log.e(TAG, "GeoPictureUploader.writeFormField: got: " + e.getMessage()); } } /** * write one file field to dataSream * @param fieldName - name of file field * @param fieldValue - file name * @param type - mime type * @param fileInputStream - stream of bytes that get sent up */ private void writeFileField( String fieldName, String fieldValue, String type, FileInputStream fis) { try { // opening boundary line dataStream.writeBytes(twoHyphens + boundary + CRLF); dataStream.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\";filename=\"" + fieldValue + "\"" + CRLF); dataStream.writeBytes("Content-Type: " + type + CRLF); dataStream.writeBytes(CRLF); // create a buffer of maximum size int bytesAvailable = fis.available(); int maxBufferSize = 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); byte[] buffer = new byte[bufferSize]; // read file and write it into form... int bytesRead = fis.read(buffer, 0, bufferSize); while (bytesRead > 0) { dataStream.write(buffer, 0, bufferSize); bytesAvailable = fis.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fis.read(buffer, 0, bufferSize); } // closing CRLF dataStream.writeBytes(CRLF); } catch(Exception e) { Log.e(TAG, "GeoPictureUploader.writeFormField: got: " + e.getMessage()); } } /** * @param args */ /*public static void main(String[] args) { if (args.length >= 0) { GeoPictureUploader gpu = new GeoPictureUploader("john", "aba354Geo"); String picName = args[0]; ReturnCode rc = gpu.uploadPicture(picName); System.out.printf("done"); } }*/ } --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---