Android Java HTTP Post .bin file

Viewed 70

I am trying to upload a .bin file from an Android Java mobile app to an ESP32 web server. I know the upload is working as I can test it on a web browser, but I have tried different solutions from StackOverflow such Volley, httpClient etc but it crashes on the transfer.

Any help how to complete the file upload, looks quite simple as it's just an HTTP post file transfer, but cannot get it work.

http code

    xhttp.open("POST", upload_path, true);
    xhttp.send(file);

Android code

public void uploadfile() throws Exception
{
    try {

        File file = new File("/storage/emulated/0/Download/testfile.bin");
        if (file.exists()) {

            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost uploadFile = new HttpPost("http://10.10.10.1/upload/");
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
           // builder.addTextBody("field1", "yes", ContentType.DEFAULT_BINARY);

           // This attaches the file to the POST:
            File f = new File("/storage/emulated/0/Download/testfile.bin");
            builder.addBinaryBody(
                    "file",
                    new FileInputStream(f),
                    ContentType.DEFAULT_BINARY,
                    f.getName()
            );

            HttpEntity multipart = builder.build();
            uploadFile.setEntity(multipart);
            // Code is crashing here 
            CloseableHttpResponse response = httpClient.execute(uploadFile);
            HttpEntity responseEntity = response.getEntity();
        }
    }
    catch (Exception e)
    {
        Log.d("Debug", "Catch - software activity 1050");
    }
}

=== Update ===

I have updated the code to the following and now getting a "java.net.SocketException: Connection reset" error. Not sure if the contentType needs to change, as it's a binary file using the reference (https://square.github.io/okhttp/3.x/okhttp/index.html?okhttp3/MediaType.html) not sure what else it could expect for a text file.

I have a server 500 error, so it must be communicating with the server.

   file = new File("/storage/emulated/0/Download/test-1.fw"); 
                filename = "test-1.fw";
                final MediaType contentType = MediaType.parse("text/plain");
                RequestBody requestBody = new MultipartBody.Builder()

                        .setType(MultipartBody.FORM)
                        .addFormDataPart("test-1.fw", filename, RequestBody.create(file,contentType))
                        .build();
                Request request = new Request.Builder()
                        .url("http://10.10.2.0/upload/file.bin")
                        .post(requestBody)
                        .build();

                try (Response response = client.newCall(request).execute()) {
                    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                    System.out.println(response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }

Manifest file

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2 Answers

It would be useful to have the stack trace of the exception, in order to identify the cause of the issue. Another useful information that you could provide is the Android version you are running.
Possible causes for http failure in Android app may be:

  1. In the Android manifest the internet permission is missing?
    Solution: add following statements in AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  2. You are using http protocol, but from Android 9 this protocol is restricted
    Solution 1: use https protocol instead of http
    Solution 2: add in AndroidManifest.xml the usesCleartextTraffic attribute:

    android:usesCleartextTraffic="true"

So in the end if I removed the header body it worked, the server side did not like the html content. So quite easy and works using the following

   file = new File("/storage/emulated/0/Download/test-1.fw"); 
            filename = "test-1.fw";
            final MediaType contentType = MediaType.parse("text/plain");
            RequestBody requestBody = new MultipartBody.Builder()

                
                    .addFormDataPart("test-1.fw", filename, RequestBody.create(file,contentType))
                    .build();
            Request request = new Request.Builder()
                    .url("http://10.10.2.0/upload/file.bin")
                    .post(requestBody)
                    .build();

            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                System.out.println(response.body().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
Related