Java android upload files

upload any file from any folder from sd card to server using Android

I am new for Android. I am trying to upload any type of file(like audio,video,document,image.. formats) from android SD card to php server, but am not getting clear code.I got some solution here ,but they mentioned existing particular type of file & Specific path.I want all type of fie upload from SD card.

The code in the link doesn’t filter on the extension neither the mime type, that should work for you.

Thanks for quick response Loic. I dont know how to upload mine type and pick file from SD card.I dont want mention existing file name.If have idea share me.

2 Answers 2

from this method u can access all file from sd card this is my code

 public void getAllFile(File dir) < File listFile[] = dir.listFiles(); if (listFile != null) < for (int i = 0; i < listFile.length; i++) < if (listFile[i].isDirectory()) < getAllFile(listFile[i]); >else < listFile[i].getName(); System.out.println("your file is "+listFile[i].getName()); >> > > 

//call this method to select file from device memory

 static Uri url; String path; private void showFileChooser() < Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.setType("*/*"); i.addCategory(Intent.CATEGORY_OPENABLE); i = Intent.createChooser(i, "Choose a file"); startActivityForResult(i, FILE_SELECT_CODE); >

//here you will get the path of selected file

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) < if(resultCode==-1) < Log.w("Request Code", ""+requestCode); Log.w("Result Code", ""+resultCode); path = getRealPathFromURI( data.getData()); try < Log.w("Intent", data.getData().toString()); >catch (Exception e) < // TODO Auto-generated catch block Log.w("Error", e.toString()); >> > 

//get exact path of file — exact path is stored in path variable

public String getRealPathFromURI (Uri contentUri) < String path = null; String[] proj = < MediaStore.MediaColumns.DATA >; if("content".equalsIgnoreCase(contentUri.getScheme ())) < Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null); if (cursor.moveToFirst()) < int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); path = cursor.getString(column_index); >cursor.close(); return path; > else if("file".equalsIgnoreCase(contentUri.getScheme())) < return contentUri.getPath(); >return null; > 

Источник

Читайте также:  Java lang exception no tests found matching method junit

Sending files using POST with HttpURLConnection

Since the Android developers recommend to use the HttpURLConnection class, I was wondering if anyone can provide me with a good example on how to send a bitmap «file» (actually an in-memory stream) via POST to an Apache HTTP server. I’m not interested in cookies or authentication or anything complicated, but I just want to have a reliable and logic implementation. All the examples that I’ve seen around here look more like «let’s try this and maybe it works». Right now, I have this code:

URL url; HttpURLConnection urlConnection = null; try < url = new URL("http://example.com/server.cgi"); urlConnection = (HttpURLConnection) url.openConnection(); >catch (Exception e) < this.showDialog(getApplicationContext(), e.getMessage()); >finally < if (urlConnection != null) < urlConnection.disconnect(); >> 

where showDialog should just display an AlertDialog (in case of an invalid URL?). Now, let’s say that I generate a bitmap like so: Bitmap image = this.getBitmap() inside a control derived from View and I want to send it via POST. What would be the proper procedure to achieve such a thing? What classes do I need to use? Can I use HttpPost like in this example? If so, how would I construct the InputStreamEntity for my bitmap? I would find it revolting to be required to first store the bitmap in a file on the device. I should also mention that I really need to send every unaltered pixel of the original bitmap to the server, so I can’t convert it to JPEG.

8 Answers 8

I have no idea why the HttpURLConnection class does not provide any means to send files without having to compose the file wrapper manually. Here’s what I ended up doing, but if someone knows a better solution, please let me know.

Bitmap bitmap = myView.getBitmap(); 
String attachmentName = "bitmap"; String attachmentFileName = "bitmap.bmp"; String crlf = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; 
HttpURLConnection httpUrlConnection = null; URL url = new URL("http://example.com/server.cgi"); httpUrlConnection = (HttpURLConnection) url.openConnection(); httpUrlConnection.setUseCaches(false); httpUrlConnection.setDoOutput(true); httpUrlConnection.setRequestMethod("POST"); httpUrlConnection.setRequestProperty("Connection", "Keep-Alive"); httpUrlConnection.setRequestProperty("Cache-Control", "no-cache"); httpUrlConnection.setRequestProperty( "Content-Type", "multipart/form-data;boundary Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf); request.writeBytes(this.crlf); 

Convert Bitmap to ByteBuffer :

//I want to send only 8 bit black & white bitmaps byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()]; for (int i = 0; i < bitmap.getWidth(); ++i) < for (int j = 0; j < bitmap.getHeight(); ++j) < //we're interested only in the MSB of the first byte, //since the other 3 bytes are identical for B&W images pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7); > > request.write(pixels); 
request.writeBytes(this.crlf); request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf); 
request.flush(); request.close(); 
InputStream responseStream = new BufferedInputStream(httpUrlConnection.getInputStream()); BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream)); String line = ""; StringBuilder stringBuilder = new StringBuilder(); while ((line = responseStreamReader.readLine()) != null) < stringBuilder.append(line).append("\n"); >responseStreamReader.close(); String response = stringBuilder.toString(); 
httpUrlConnection.disconnect(); 

PS: Of course I had to wrap the request in private class AsyncUploadBitmaps extends AsyncTask , in order to make the Android platform happy, because it doesn’t like to have network requests on the main thread.

Finally a perfectly explained answer for this question! Thank you! BTW, I just found this article from the Android Developers Blog (android-developers.blogspot.com/2011/09/…) where they suggest using HTTPURLConnection over the Apache HTTPClient. Cheers!

PS: According to this, ` [error] => 3` means that «the uploaded file was only partially uploaded», so I can assume that there are some buffering issues, but I have no idea how to debug / fix something like this.

See my comment just above. You need to add them to the url variable, like so: URL url = new URL(«http://example.com/?param1=val1&param2=val2»); . You can add as many as you wish (although I think there are some limits).

Excellent, just misses one thing: that responseStreamReader should be closed in the finally of the try/catch. This way: try < ALL YOUR CODE >catch (IOException e) < e.printStackTrace(); >finally < if (connection != null) connection.disconnect(); try < if (responseStreamReader != null) responseStreamReader.close(); >catch (IOException e) < e.printStackTrace(); >>

I actually found a better way to send files using HttpURLConnection using MultipartEntity

private static String multipost(String urlString, MultipartEntity reqEntity) < try < URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(10000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setUseCaches(false); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Connection", "Keep-Alive"); conn.addRequestProperty("Content-length", reqEntity.getContentLength()+""); conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue()); OutputStream os = conn.getOutputStream(); reqEntity.writeTo(conn.getOutputStream()); os.close(); conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) < return readStream(conn.getInputStream()); >> catch (Exception e) < Log.e(TAG, "multipart post error " + e + "(" + urlString + ")"); >return null; > private static String readStream(InputStream in) < BufferedReader reader = null; StringBuilder builder = new StringBuilder(); try < reader = new BufferedReader(new InputStreamReader(in)); String line = ""; while ((line = reader.readLine()) != null) < builder.append(line); >> catch (IOException e) < e.printStackTrace(); >finally < if (reader != null) < try < reader.close(); >catch (IOException e) < e.printStackTrace(); >> > return builder.toString(); > 

Assuming you are uploading an image with bitmap data:

 Bitmap bitmap = . ; String filename = "filename.png"; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), filename); MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); reqEntity.addPart("picture", contentPart); String response = multipost("http://server.com", reqEntity); 

And Voila! Your post data will contain picture field along with the filename and path on your server.

@MihaiTodor You will want to compress the bitmap into a File to reduce the amount of data passed over network anyway.

you should call setFixedLengthStreamingMode(reqEntity.getContentLength()) instead of setting the Content-Length header directly. This way your data isn’t buffered before sending on the socket (at least on newer devices, on android 2.3 or less it seems they get buffered anyways). I fixed the buffering issue on older devices by using okhttp as the transport and that works.

@mente It is bundled with the httpmime. I use this as a Gradle dependency: org.apache.httpcomponents:httpmime:4.1.1

The solution of Jaydipsinh Zala didn’t work for me, I don’t know why but it seems to be close to the solution.

So merging this one with the great solution and explanation of Mihai Todor, the result is this class that currently works for me. If it helps someone:

import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.file.Files; public class MultipartUtilityV2 < private HttpURLConnection httpConn; private DataOutputStream request; private final String boundary = "*****"; private final String crlf = "\r\n"; private final String twoHyphens = "--"; /** * This constructor initializes a new HTTP POST request with content type * is set to multipart/form-data * * @param requestURL * @throws IOException */ public MultipartUtilityV2(String requestURL) throws IOException < // creates a unique boundary based on time stamp URL url = new URL(requestURL); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setUseCaches(false); httpConn.setDoOutput(true); // indicates POST method httpConn.setDoInput(true); httpConn.setRequestMethod("POST"); httpConn.setRequestProperty("Connection", "Keep-Alive"); httpConn.setRequestProperty("Cache-Control", "no-cache"); httpConn.setRequestProperty( "Content-Type", "multipart/form-data;boundary=" + this.boundary); request = new DataOutputStream(httpConn.getOutputStream()); >/** * Adds a form field to the request * * @param name field name * @param value field value */ public void addFormField(String name, String value)throws IOException < request.writeBytes(this.twoHyphens + this.boundary + this.crlf); request.writeBytes("Content-Disposition: form-data; name=\"" + name + "\""+ this.crlf); request.writeBytes("Content-Type: text/plain; charset=UTF-8" + this.crlf); request.writeBytes(this.crlf); request.writeBytes(value+ this.crlf); request.flush(); >/** * Adds a upload file section to the request * * @param fieldName name attribute in * @param uploadFile a File to be uploaded * @throws IOException */ public void addFilePart(String fieldName, File uploadFile) throws IOException < String fileName = uploadFile.getName(); request.writeBytes(this.twoHyphens + this.boundary + this.crlf); request.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\";filename=\"" + fileName + "\"" + this.crlf); request.writeBytes(this.crlf); byte[] bytes = Files.readAllBytes(uploadFile.toPath()); request.write(bytes); >/** * Completes the request and receives response from the server. * * @return a list of Strings as response in case the server returned * status OK, otherwise an exception is thrown. * @throws IOException */ public String finish() throws IOException < String response =""; request.writeBytes(this.crlf); request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf); request.flush(); request.close(); // checks server's status code first int status = httpConn.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) < InputStream responseStream = new BufferedInputStream(httpConn.getInputStream()); BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream)); String line = ""; StringBuilder stringBuilder = new StringBuilder(); while ((line = responseStreamReader.readLine()) != null) < stringBuilder.append(line).append("\n"); >responseStreamReader.close(); response = stringBuilder.toString(); httpConn.disconnect(); > else < throw new IOException("Server returned non-OK status: " + status); >return response; > > 

but why you don’t flush at the end of addFilePart() ? i saw you did flushing for the end of addFormField() . @Georgevik

This answer https://stackoverflow.com/a/33149413/6481542 got me 90% of the way with uploading large files to a development Django server, but I had to use setFixedLengthStreamingMode to make it worked. That requires setting the Content-Length before writing the content, thus requiring a fairly significant rewrite of the above answer. Here’s my end result

public class MultipartLargeUtility < private final String boundary; private static final String LINE_FEED = "\r\n"; private HttpURLConnection httpConn; private String charset; private OutputStream outputStream; private PrintWriter writer; private final int maxBufferSize = 4096; private long contentLength = 0; private URL url; private Listfields; private List files; private class FormField < public String name; public String value; public FormField(String name, String value) < this.name = name; this.value = value; >> private class FilePart < public String fieldName; public File uploadFile; public FilePart(String fieldName, File uploadFile) < this.fieldName = fieldName; this.uploadFile = uploadFile; >> /** * This constructor initializes a new HTTP POST request with content type * is set to multipart/form-data * * @param requestURL * @param charset * @throws IOException */ public MultipartLargeUtility(String requestURL, String charset, boolean requireCSRF) throws IOException < this.charset = charset; // creates a unique boundary based on time stamp boundary = "===" + System.currentTimeMillis() + "==="; url = new URL(requestURL); fields = new ArrayList<>(); files = new ArrayList<>(); if (requireCSRF) < getCSRF(); >> /** * Adds a form field to the request * * @param name field name * @param value field value */ public void addFormField(String name, String value) throws UnsupportedEncodingException < String fieldContent = "--" + boundary + LINE_FEED; fieldContent += "Content-Disposition: form-data; name=\"" + name + "\"" + LINE_FEED; fieldContent += "Content-Type: text/plain; charset=" + charset + LINE_FEED; fieldContent += LINE_FEED; fieldContent += value + LINE_FEED; contentLength += fieldContent.getBytes(charset).length; fields.add(new FormField(name, value)); >/** * Adds a upload file section to the request * * @param fieldName name attribute in * @param uploadFile a File to be uploaded * @throws IOException */ public void addFilePart(String fieldName, File uploadFile) throws IOException < String fileName = uploadFile.getName(); String fieldContent = "--" + boundary + LINE_FEED; fieldContent += "Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"" + LINE_FEED; fieldContent += "Content-Type: " + URLConnection.guessContentTypeFromName(fileName) + LINE_FEED; fieldContent += "Content-Transfer-Encoding: binary" + LINE_FEED; fieldContent += LINE_FEED; // file content would go here fieldContent += LINE_FEED; contentLength += fieldContent.getBytes(charset).length; contentLength += uploadFile.length(); files.add(new FilePart(fieldName, uploadFile)); >/** * Adds a header field to the request. * * @param name - name of the header field * @param value - value of the header field */ //public void addHeaderField(String name, String value) < // writer.append(name + ": " + value).append(LINE_FEED); // writer.flush(); //>/** * Completes the request and receives response from the server. * * @return a list of Strings as response in case the server returned * status OK, otherwise an exception is thrown. * @throws IOException */ public List finish() throws IOException < Listresponse = new ArrayList(); String content = "--" + boundary + "--" + LINE_FEED; contentLength += content.getBytes(charset).length; if (!openConnection()) < return response; >writeContent(); // checks server's status code first int status = httpConn.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) < BufferedReader reader = new BufferedReader(new InputStreamReader( httpConn.getInputStream())); String line = null; while ((line = reader.readLine()) != null) < response.add(line); >reader.close(); httpConn.disconnect(); > else < throw new IOException("Server returned non-OK status: " + status); >return response; > private boolean getCSRF() throws IOException < /// First, need to get CSRF token from server /// Use GET request to get the token CookieManager cookieManager = new CookieManager(); CookieHandler.setDefault(cookieManager); HttpURLConnection conn = null; conn = (HttpURLConnection) url.openConnection(); conn.setUseCaches(false); // Don't use a Cached Copy conn.setRequestMethod("GET"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.getContent(); conn.disconnect(); /// parse the returned object for the CSRF token CookieStore cookieJar = cookieManager.getCookieStore(); Listcookies = cookieJar.getCookies(); String csrf = null; for (HttpCookie cookie : cookies) < Log.d("cookie", "" + cookie); if (cookie.getName().equals("csrftoken")) < csrf = cookie.getValue(); break; >> if (csrf == null) < Log.d(TAG, "Unable to get CSRF"); return false; >Log.d(TAG, "Received cookie: " + csrf); addFormField("csrfmiddlewaretoken", csrf); return true; > private boolean openConnection() throws IOException < httpConn = (HttpURLConnection) url.openConnection(); httpConn.setUseCaches(false); httpConn.setDoOutput(true); // indicates POST method httpConn.setDoInput(true); //httpConn.setRequestProperty("Accept-Encoding", "identity"); httpConn.setFixedLengthStreamingMode(contentLength); httpConn.setRequestProperty("Connection", "Keep-Alive"); httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); outputStream = new BufferedOutputStream(httpConn.getOutputStream()); writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true); return true; >private void writeContent() throws IOException < for (FormField field : fields) < writer.append("--" + boundary).append(LINE_FEED); writer.append("Content-Disposition: form-data; name=\"" + field.name + "\"") .append(LINE_FEED); writer.append("Content-Type: text/plain; charset=" + charset).append( LINE_FEED); writer.append(LINE_FEED); writer.append(field.value).append(LINE_FEED); writer.flush(); >for (FilePart filePart : files) < String fileName = filePart.uploadFile.getName(); writer.append("--" + boundary).append(LINE_FEED); writer.append( "Content-Disposition: form-data; name=\"" + filePart.fieldName + "\"; filename=\"" + fileName + "\"") .append(LINE_FEED); writer.append( "Content-Type: " + URLConnection.guessContentTypeFromName(fileName)) .append(LINE_FEED); writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED); writer.append(LINE_FEED); writer.flush(); FileInputStream inputStream = new FileInputStream(filePart.uploadFile); int bufferSize = Math.min(inputStream.available(), maxBufferSize); byte[] buffer = new byte[bufferSize]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) != -1) < outputStream.write(buffer, 0, bytesRead); >outputStream.flush(); inputStream.close(); writer.append(LINE_FEED); writer.flush(); > writer.append("--" + boundary + "--").append(LINE_FEED); writer.close(); > > 

Usage is largely the same as in the above answer, but I’ve included CSRF support that Django uses by default with forms

boolean useCSRF = true; MultipartLargeUtility multipart = new MultipartLargeUtility(url, "UTF-8",useCSRF); multipart.addFormField("param1","value"); multipart.addFilePart("filefield",new File("/path/to/file")); List response = multipart.finish(); Log.w(TAG,"SERVER REPLIED:"); for(String line : response)

Источник

How do I send a file in Android from a mobile device to server using http?

Easy, you can use a Post request and submit your file as binary (byte array).

String url = "http://yourserver"; File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "yourfile"); try < HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); InputStreamEntity reqEntity = new InputStreamEntity( new FileInputStream(file), -1); reqEntity.setContentType("binary/octet-stream"); reqEntity.setChunked(true); // Send in multiple parts if needed httppost.setEntity(reqEntity); HttpResponse response = httpclient.execute(httppost); //Do something with response. >catch (Exception e) < // show error >

What should I do if I want to send some data in request body along with file? i.e. send file and also request body?

This can be done with a HTTP Post request to the server:

HttpClient http = AndroidHttpClient.newInstance("MyApp"); HttpPost method = new HttpPost("http://url-to-server"); method.setEntity(new FileEntity(new File("path-to-file"), "application/octet-stream")); HttpResponse response = http.execute(method); 

in my case it’s throwing an error ,IllegalStateException AndroidHttpClient was never closed, I don’t know how to circumvent it.

Your mileage may vary, but for me this returned an empty set of $_FILES at the server side. Using the MultiPart stuff fixed it. stackoverflow.com/questions/1067655/…

What is the default $_FILES[‘file’] name going to be if you don’t set one? is it just basename($_FILES[‘file’][‘tmp_name’])

the most effective method is to use android-async-http

You can use this code to upload a file:

// gather your request parameters File myFile = new File("/path/to/file.png"); RequestParams params = new RequestParams(); try < params.put("profile_picture", myFile); >catch(FileNotFoundException e) <> // send request AsyncHttpClient client = new AsyncHttpClient(); client.post(url, params, new AsyncHttpResponseHandler() < @Override public void onSuccess(int statusCode, Header[] headers, byte[] bytes) < // handle success response >@Override public void onFailure(int statusCode, Header[] headers, byte[] bytes, Throwable throwable) < // handle failure response >>); 

Note that you can put this code directly into your main Activity, no need to create a background Task explicitly. AsyncHttp will take care of that for you!

Источник

Оцените статью