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
-~----------~----~----~----~------~----~------~--~---

Reply via email to