71

In android, how do I send a file(data) from a mobile device to server using http.

unicorn2
  • 844
  • 13
  • 30
Subrat
  • 3,928
  • 6
  • 39
  • 48

6 Answers6

84

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
}
Community
  • 1
  • 1
Emmanuel
  • 16,791
  • 6
  • 48
  • 74
  • 2
    What's the name of the parameter to receive the file in the server? – sanrodari Feb 08 '12 at 20:27
  • 1
    @sanrodari: you get file in $_FILES array – toni May 30 '12 at 06:28
  • 2
    My $_FILES remains empty, I see a lot of other posts using MultipartEntity. Do I need that instead? – RvdK Jun 12 '12 at 13:06
  • @PoweRoy: It depends. Do you want to send a single file, or multiple files? For multiple files, they must be wrapped into a single container. – Emmanuel Jun 22 '12 at 15:16
  • 4
    Can you please give a reference to ASP.NET server side code for the above code snippet? – Sreekanth Karumanaghat Jul 26 '13 at 10:14
  • 1
    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? – SamFast Nov 19 '16 at 13:09
  • @SojharoMangi For that you need to send a MultipartEntity as in http://stackoverflow.com/a/24240424 – Emmanuel Nov 20 '16 at 02:05
  • This should, of course, be done in a worker thread. Otherwise you will get NetworkOnMainThreadException. – Jeff.H Aug 24 '17 at 20:50
  • I still not understand how to get name of that parameter – Dita Aji Pratama Jul 31 '18 at 08:36
  • @DitaAjiPratama I'm not sure I understand your question. When you say the "name of that parameter" do you mean the file name? The file name is not passed in. You'll have to pass it in some other way such as URL parameter or header and artificially retrieve it on the other side. The only standard way around is to use a multipart/form-data which allows passing the file name as a Content-Disposition parameter of each part. See https://stackoverflow.com/a/2793153/442512 – Emmanuel Jul 31 '18 at 14:34
  • @DitaAjiPratama This is a question Java/Android on the client side. I don't think that $_FILES['name'] is in Java. It seems to be PHP (server side). In which case, what I wrote is a valid answer (Content-Disposition parameter for each part) on the client part of the PHP. – Emmanuel Aug 01 '18 at 15:40
  • @atishr sorry it was a hypothetical server PHP script. I don't know PHP. But I think this answer could help you: https://stackoverflow.com/a/36863148/442512 – Emmanuel May 03 '19 at 21:19
16

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);
cobbal
  • 69,903
  • 20
  • 143
  • 156
DaGGeRRz
  • 1,611
  • 1
  • 12
  • 13
  • 2
    in my case it's throwing an error ,IllegalStateException AndroidHttpClient was never closed, I don't know how to circumvent it. – Vaibhav Mishra Nov 15 '11 at 10:20
  • Your mileage may vary, but for me this returned an empty set of $_FILES at the server side. Using the MultiPart stuff fixed it. http://stackoverflow.com/questions/1067655/how-to-upload-a-file-using-java-httpclient-library-working-with-php-strange-pr – Chris Rae Nov 30 '12 at 01:08
  • 1
    What is the default `$_FILES['file']` name going to be if you don't set one? is it just `basename($_FILES['file']['tmp_name'])` – Brandon Aug 12 '15 at 20:05
10

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!

juffel
  • 1,045
  • 15
  • 21
Hoshouns
  • 2,420
  • 23
  • 24
  • how to use this to upload multiple files? note I must wait until the response return to upload the next file, I tried to use this inside for loop but the for loop didn't wait until the response return... – mostafa hashim Jul 12 '16 at 18:43
9

Wrap it all up in an Async task to avoid threading errors.

public class AsyncHttpPostTask extends AsyncTask<File, Void, String> {

    private static final String TAG = AsyncHttpPostTask.class.getSimpleName();
    private String server;

    public AsyncHttpPostTask(final String server) {
        this.server = server;
    }

    @Override
    protected String doInBackground(File... params) {
        Log.d(TAG, "doInBackground");
        HttpClient http = AndroidHttpClient.newInstance("MyApp");
        HttpPost method = new HttpPost(this.server);
        method.setEntity(new FileEntity(params[0], "text/plain"));
        try {
            HttpResponse response = http.execute(method);
            BufferedReader rd = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));
            final StringBuilder out = new StringBuilder();
            String line;
            try {
                while ((line = rd.readLine()) != null) {
                    out.append(line);
                }
            } catch (Exception e) {}
            // wr.close();
            try {
                rd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // final String serverResponse = slurp(is);
            Log.d(TAG, "serverResponse: " + out.toString());
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
slott
  • 3,266
  • 1
  • 35
  • 30
4

the most effective method is to use org.apache.http.entity.mime.MultipartEntity;

see this code from the link using org.apache.http.entity.mime.MultipartEntity;

public class SimplePostRequestTest3 {

  /**
   * @param args
   */
  public static void main(String[] args) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://localhost:8080/HTTP_TEST_APP/index.jsp");

    try {
      FileBody bin = new FileBody(new File("C:/ABC.txt"));
      StringBody comment = new StringBody("BETHECODER HttpClient Tutorials");

      MultipartEntity reqEntity = new MultipartEntity();
      reqEntity.addPart("fileup0", bin);
      reqEntity.addPart("fileup1", comment);

      reqEntity.addPart("ONE", new StringBody("11111111"));
      reqEntity.addPart("TWO", new StringBody("222222222"));
      httppost.setEntity(reqEntity);

      System.out.println("Requesting : " + httppost.getRequestLine());
      ResponseHandler<String> responseHandler = new BasicResponseHandler();
      String responseBody = httpclient.execute(httppost, responseHandler);

      System.out.println("responseBody : " + responseBody);

    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      httpclient.getConnectionManager().shutdown();
    }
  }

}

Added:

Example Link

Zaffar Saffee
  • 6,167
  • 5
  • 39
  • 77
jitain sharma
  • 584
  • 5
  • 19
2

For anyone still trying, you could try with retrofit2 this link.

C-Bk
  • 321
  • 1
  • 7