Awesome, thanks for sharing the code. :) Does it need a specific version of HttpClient, different than the one that comes with the platform?
And for communicating status and progress back up to a UI thread, AsyncTask in 1.5 would be perfect. Also, what license is this code snippet released under? Thanks again for sharing! :) j On Sun, May 10, 2009 at 5:04 AM, Anna PS <annapowellsm...@googlemail.com> wrote: > > I'm starting a new thread, in response to a request over here: > http://bit.ly/E1Qqm > > This is some sample code for uploading an image to the web, as part of > a multipart message. It assumes that the photo is stored on the SD > card as "photo.jpg". You'll need to download and add a couple of jar > files to the project's built path - commons-httpclient.jar and > httpcomponents-client-4.0-alpha4. > > It is working on my device. However (big caveats here) - it's much > slower than I would like, and much slower than other applications I've > installed that upload photos. It also feels hacky - e.g. the way the > background thread communicates problems with the upload to the main > thread using variables. I'm sure there must be a neater way to do it. > > If you figure out a way to improve the code, please post suggestions > here! > > cheers, > Anna > > ------------------------------------- > > private static final int LOCATION_NOT_FOUND = 1; > private static final int UPLOAD_ERROR = 2; > final Runnable mUpdateResults = new Runnable() { > public void run() { > pd.dismiss(); > updateResultsInUi(); > } > }; > > public void onCreate(Bundle icicle) { > super.onCreate(icicle); > setContentView(R.layout.home); > > // do some stuff and then, when you want to upload a > photo.... > uploadToWeb(); > } > > // > ********************************************************************** > // uploadToWeb: uploads details, handled via a background thread > // > ********************************************************************** > private void uploadToWeb() { > Log.d(LOG_TAG, "uploadToWeb"); > pd = ProgressDialog > .show( > this, > "Uploading, please wait...", > "Uploading. This can take > several seconds, depending on your > connection speed. Please be patient!", > true, false); > Thread t = new Thread() { > public void run() { > doUploadinBackground(); > mHandler.post(mUpdateResults); > } > }; > t.start(); > } > > private void updateResultsInUi() { > if (globalStatus == UPLOAD_ERROR) { > showDialog(UPLOAD_ERROR); > > } else if (globalStatus == LOCATION_NOT_FOUND) { > showDialog(LOCATION_NOT_FOUND); > > } else if (globalStatus == PHOTO_NOT_FOUND) { > showDialog(PHOTO_NOT_FOUND); > > } else { > // Success! - Proceed to the success activity! > Intent i = new Intent(Home.this, Success.class); > startActivity(i); > } > } > > // > ********************************************************************** > // onCreateDialog: Dialog warnings > // > ********************************************************************** > �...@override > protected Dialog onCreateDialog(int id) { > switch (id) { > case UPLOAD_ERROR: > return new AlertDialog.Builder(Home.this) > .setTitle("Upload error") > .setPositiveButton("OK", > new > DialogInterface.OnClickListener() { > public void > onClick(DialogInterface dialog, > > int whichButton) { > } > }) > .setMessage( > "Sorry, there was an > error uploading. Please try again later.") > .create(); > case LOCATION_NOT_FOUND: > return new AlertDialog.Builder(Home.this) > .setTitle("Location problem") > .setPositiveButton("OK", > new > DialogInterface.OnClickListener() { > public void > onClick(DialogInterface dialog, > > int whichButton) { > } > }) > .setMessage( > "Could not get > location! Can you see the sky? Please try again > later.") > .create(); > } > return null; > } > > // > ********************************************************************** > // doUploadinBackground: POST request > // > ********************************************************************** > private boolean doUploadinBackground() { > Log.d(LOG_TAG, "doUploadinBackground"); > String responseString = null; > PostMethod method; > > if ((latitude != null) && (longitude != null)) { > latString = latitude.toString(); > longString = longitude.toString(); > Log.e(LOG_TAG, "Latitude = " + latString); > Log.e(LOG_TAG, "Longitude = " + longString); > } else { > Log.e(LOG_TAG, "Location is null"); > globalStatus = LOCATION_NOT_FOUND; > return false; > } > > method = new PostMethod("yoururlhere"); > > try { > > byte[] imageByteArray = null; > > HttpClient client = new HttpClient(); > > client.getHttpConnectionManager().getParams().setConnectionTimeout( > 100000); > > File f = new > File(Environment.getExternalStorageDirectory(), > "photo.jpg"); > > imageByteArray = getBytesFromFile(f); > > Log > .d(LOG_TAG, "len of data is " + > imageByteArray.length > + " bytes"); > > FilePart photo = new FilePart("photo", new > ByteArrayPartSource( > "photo", imageByteArray)); > > photo.setContentType("image/jpeg"); > photo.setCharSet(null); > > Part[] parts = { new StringPart("service", "Android > mobile"), > new StringPart("subject", subject), > new StringPart("name", name), > new StringPart("email", email), > new StringPart("lat", latString), > new StringPart("lon", longString), > photo }; > > method.setRequestEntity(new > MultipartRequestEntity(parts, method > .getParams())); > > client.executeMethod(method); > responseString = method.getResponseBodyAsString(); > method.releaseConnection(); > > Log.e("httpPost", "Response status: " + > responseString); > Log.e("httpPost", "Latitude = " + latString + " and > Longitude = " > + longString); > > } catch (Exception ex) { > Log.v(LOG_TAG, "Exception", ex); > return false; > } finally { > method.releaseConnection(); > } > > if (responseString.equals("SUCCESS")) { > // launch the Success page > return true; > } else { > globalStatus = UPLOAD_ERROR; > return false; > } > } > > // read the photo file into a byte array... > public static byte[] getBytesFromFile(File file) throws IOException { > InputStream is = new FileInputStream(file); > // Get the size of the file > long length = file.length(); > // You cannot create an array using a long type. > // It needs to be an int type. > // Before converting to an int type, check > // to ensure that file is not larger than Integer.MAX_VALUE. > if (length > Integer.MAX_VALUE) { > // File is too large > } > > // Create the byte array to hold the data > byte[] bytes = new byte[(int) length]; > // Read in the bytes > int offset = 0; > int numRead = 0; > while (offset < bytes.length > && (numRead = is.read(bytes, offset, > bytes.length - offset)) >= 0) > { > offset += numRead; > } > > // Ensure all the bytes have been read in > if (offset < bytes.length) { > throw new IOException("Could not completely read file " > + file.getName()); > } > > // Close the input stream and return bytes > is.close(); > return bytes; > } > > > > -- Jeff Sharkey jshar...@google.com --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---