How to send image data to a server with Android

I am trying to write an Android application that will take a snapshot, put the data (byte []) in the object along with some metadata and publish it on the AppEngine server, where it will be saved in the data store as a blot. I really do not want to save the image as a file on Android (unless it is necessary). I was looking for solutions to solve, but nothing clear or concrete enough came up. My questions:

  • How to send an object to my servlet? In particular, how to properly serialize an object and get serialized output in HttpPost or something similar.
  • As soon as I save the blob in the data store, how can I get it as an image to display on a web page?

Code examples would be very helpful. Also, if the approach I'm taking is too complicated or problematic, suggest other ways (for example, save the image as a file, send it to the server, and then delete).

+4
source share
5 answers

You just need to do Http-FileUpload, which in a special case is POST. No need for uuencode file. No need to use special lib / jar No need to save the object to disk (no matter what the following example does)

You will find a very good explanation of Http-Command and how your special focus is โ€œfile downloadโ€ under

Using java.net.URLConnection to start and process HTTP requests

Below is an example of downloading a file (see "Send a binary file") and you can add some information about partners either


String param = "value"; File textFile = new File("/path/to/file.txt"); File binaryFile = new File("/path/to/file.bin"); String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value. String CRLF = "\r\n"; // Line separator required by multipart/form-data. URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); PrintWriter writer = null; try { OutputStream output = connection.getOutputStream(); writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important! // Send normal param. writer.append("--" + boundary).append(CRLF); writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF); writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); writer.append(CRLF); writer.append(param).append(CRLF).flush(); // Send text file. writer.append("--" + boundary).append(CRLF); writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF); writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); writer.append(CRLF).flush(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(textFile), charset)); for (String line; (line = reader.readLine()) != null;) { writer.append(line).append(CRLF); } } finally { if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {} } writer.flush(); // Send binary file. writer.append("--" + boundary).append(CRLF); writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF); writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName()).append(CRLF); writer.append("Content-Transfer-Encoding: binary").append(CRLF); writer.append(CRLF).flush(); InputStream input = null; try { input = new FileInputStream(binaryFile); byte[] buffer = new byte[1024]; for (int length = 0; (length = input.read(buffer)) > 0;) { output.write(buffer, 0, length); } output.flush(); // Important! Output cannot be closed. Close of writer will close output as well. } finally { if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} } writer.append(CRLF).flush(); // CRLF is important! It indicates end of binary boundary. // End of multipart/form-data. writer.append("--" + boundary + "--").append(CRLF); } finally { if (writer != null) writer.close(); } 

Regarding the second part of your question. When uploading a file successfully (I use shared Apache files), it is not very important to deliver blob as an image.

Here's how to accept a file in a servlet

 public void doPost(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException { ServletFileUpload upload = new ServletFileUpload(); try { FileItemIterator iter = upload.getItemIterator (pRequest); while (iter.hasNext()) { FileItemStream item = iter.next(); String fieldName = item.getFieldName(); InputStream stream = item.openStream(); .... stream.close(); } ... 

And this code provides an image

 public void doGet (HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException { try { Blob img = (Blob) entity.getProperty(propImg); pResponse.addHeader ("Content-Disposition", "attachment; filename=abc.png"); pResponse.addHeader ("Cache-Control", "max-age=120"); String enc = "image/png"; pResponse.setContentType (enc); pResponse.setContentLength (img.getBytes().length); OutputStream out = pResponse.getOutputStream (); out.write (img.getBytes()); out.close(); 

I hope these code snippets help answer your questions.

+8
source

1. You can encode byte [] on base64 using:

http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html

2. Send this data with an HTTP POST request to your AppEngine servlet.

3.Use AppEngine to accept the servlet.

4. Then you have the choice to save it to the data warehouse or Blobstore. -I prefer blobstore for such things.

5.Decode the base64 server side.

6. From there, you need to cut your string into smaller pieces and write each piece in the blob shop.

Here is the code to write to blobstore.

 byte[] finalImageArray = null; try { finalImageArray = Base64.decode(finalImageData.getBytes()); //finalImageData is the string retrieved from the HTTP POST } catch (Base64DecoderException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try{ FileService fileService = FileServiceFactory.getFileService(); AppEngineFile file = fileService.createNewBlobFile("image/png"); FileWriteChannel writeChannel = fileService.openWriteChannel(file, true); int steps = (int) Math.floor(finalImageArray.length/1000); int current = 0; for(int i = 0; i < 1000; i++){ writeChannel.write(ByteBuffer.wrap(Arrays.copyOfRange(finalImageArray, current, steps+current))); current = current + steps; } writeChannel.write(ByteBuffer.wrap(Arrays.copyOfRange(finalImageArray, current, finalImageArray.length))); //The reason it cut up like this is because you can't write the complete string in one go. writeChannel.closeFinally(); blobKey = fileService.getBlobKey(file); if(blobKey == null) blobKey = retryBloBKey(file); //My own method, AppEngine tends to not return the blobKey once a while. } catch(Exception e){ logger.log(Level.SEVERE,e.getMessage()); } return blobKey.getKeyString(); 
  • Write a servlet in which you will receive image data with the key provided.

  • Enjoy the beautiful code :)

// The reason I save it in binary format is because it gives me the ability to play with the api image, you can also save it in base64 format.

+6
source

As the code is provided by three persons, so you can choose any of them (or you will get many examples on Google). There are three possibilities 1) first you have an image in your SD card.

2) you download the image from the server, and then send

3) Images are stored in DataBase as blob

The best approach considering each case is

1) If your image is stored in sdcard, just fecth image Convert to bitmap โ†’ byteArray โ†’ String and send to the server

2) If you download images from the server, and then send to another URL. Then load all the image URL stores into the DataBase table. If necessary, send to the server to retrieve the url, upload the image and store in the cache. Then, in the same way, send the server and update the cache

3) It is recommended not to store many images in DB. But in case you have a need for this, getBlob is converted to an array of bytes and sent to the server

Sending image to server

Reading a blog

Reading with sdcard

 List<Integer> drawablesId = new ArrayList<Integer>(); int picIndex=12345; File sdDir = new File("/sdcard/pictures"); File[] sdDirFiles = sdDir.listFiles(); for(File singleFile : sdDirFiles) { Drawable.createFromPath(singleFile.getAbsolutePath()); / you can create Bitmap from drawable } 

Hope this helps you.

+2
source
  • Android Asynchronous Http library provides a way to upload files to a web service. I used it in my projects with great success.

  • It looks like you need a web service method that takes an ID parameter and returns a file. You would save your drops in a database table with an ID index so that they can be referenced.

+1
source

Not quite sure if this is what you want, but it will present the image just as your browser will present the image as part of the form. You will need to download httmime-4.1.3.jar and add it as a link in your project.

  Bitmap bm;//whatever bitmap you are trying to send ByteArrayOutputStream bos = new ByteArrayOutputStream(); bm.compress(CompressFormat.JPEG, 75, bos); byte[] data = bos.toByteArray(); HttpClient httpClient = new DefaultHttpClient(); HttpPost postRequest = new HttpPost("http://yourwebsite.com/whatever"); ByteArrayBody bab = new ByteArrayBody(data, "image name"); MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); reqEntity.addPart("photo", bab);//"photo" is the name of the field that the image is submitted as. postRequest.setEntity(reqEntity); try { HttpResponse response = httpClient.execute(postRequest); } catch (ClientProtocolException e) { Log.e("asdf", e.getMessage(), e); } catch (IOException e) { Log.e("asdf", e.getMessage(), e); } 
+1
source

Source: https://habr.com/ru/post/1379527/


All Articles