Upload file to server using OKHTTP 3 with progress bar Android

people

Aneh Thakur

. 6 min read

In this tutorial I will explain to you how we can upload Image using OKHTTP 3 with progress bar. If you want to learn about how we can send data using OKHTTP 3 please check these post first.

Now we can start with creating a new android project or you can implement this in your existing project and follow below simple steps.

Step 1. Create new Android Studio project.

Step 2. Implement OKHttp3 library in your project

plaintext
implementation("com.squareup.okhttp3:okhttp:4.2.0")

Step 3. Add Internet and Read storage permission

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

Step 4. I’m using Dexter library for run time permission to read external storage. You can add manually permission check if you don’t want to use library read this post to add manually permission to the application.

plaintext
implementation 'com.karumi:dexter:5.0.0'

Step 5. Now open your activity_main.xml file and add bellow code.

plaintext
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imagePreview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/selectImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Select Image" />

    <Button
        android:id="@+id/upload"
        android:layout_marginTop="10dp"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:text="Upload" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:max="100"
        android:progress="0"
        android:layout_gravity="center_vertical"
        android:visibility="gone" />

</LinearLayout>

Above layout is very easy to understand. The layout contains ImageView to preview selected Image, Two-button one for select image and other for upload image to server and progress bar which show upload progress.

Step 6. Now in our project, I create a package (utils) and add class CountingRequestBody with the help of this class we are able to get upload progress in OKHTTP 3. (You get this class when you download the project).

Image

Step 7. Now open MainActivity file and first we need to find all button and view and also request for permission.

plaintext
private static final String TAG = "MainActivity";
Button selectImage, upload;
private static final int READ_REQUEST_CODE = 42;
ImageView imagePreview;
Uri uri;
ProgressBar progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Dexter.withActivity(this)
            .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
            .withListener(new PermissionListener() {
                @Override public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
                @Override public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}
                @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {/* ... */}
            }).check();

    selectImage = (Button)findViewById(R.id.selectImage);
    imagePreview = (ImageView)findViewById(R.id.imagePreview);
    upload = (Button)findViewById(R.id.upload);
    progressBar = (ProgressBar)findViewById(R.id.progressBar);

    selectImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            performFileSearch();
            upload.setVisibility(View.GONE);
        }
    });

    upload.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            progressBar.setVisibility(View.VISIBLE);
            upload.setVisibility(View.GONE);
            uploadImage();
        }
    });
}

Step 8. First, when user click on the select button we need to open choose a file via the system’s file browser with the help of below code we can do that

plaintext
public void performFileSearch() {

    // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
    // browser.
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
    intent.setType("image/*");

    startActivityForResult(intent, READ_REQUEST_CODE);
}

Step 9. Once the user selects an image or file we need to handle the selected file result in onActivityResult.@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode READ_REQUEST_CODE && resultCode Activity.RESULT_OK) { uri = null; if (data != null) { uri = data.getData(); Log.i(TAG, "Uri: " + uri.toString()); imagePreview.setImageURI(uri); upload.setVisibility(View.VISIBLE); } } }

Step 10. Now user selects the image and shows that image in preview now we need to upload that image to the server, this is the most important part of this post.

To upload file to server we need the original file path to upload we can do that with the help of bellow functions

plaintext
private String uriToFilename(Uri uri) {
    String path = null;

    if ((Build.VERSION.SDK_INT < 19) && (Build.VERSION.SDK_INT > 11)) {
        path = getRealPathFromURI_API11to18(this, uri);
    } else {
        path = getFilePath(this, uri);
    }

    return path;
}

public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
    String[] proj = {MediaStore.Images.Media.DATA};
    String result = null;
    CursorLoader cursorLoader = new CursorLoader(
            context,
            contentUri, proj, null, null, null);
    Cursor cursor = cursorLoader.loadInBackground();
    if (cursor != null) {
        int column_index =
                cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        result = cursor.getString(column_index);
    }
    return result;
}

public String getFilePath(Context context, Uri uri) {
    //Log.e("uri", uri.getPath());
    String filePath = "";
    if (DocumentsContract.isDocumentUri(context, uri)) {
        String wholeID = DocumentsContract.getDocumentId(uri);
        //Log.e("wholeID", wholeID);
        // Split at colon, use second item in the array
        String[] splits = wholeID.split(":");
        if (splits.length == 2) {
            String id = splits[1];

            String[] column = {MediaStore.Images.Media.DATA};
            // where id is equal to
            String sel = MediaStore.Images.Media._ID + "=?";
            Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    column, sel, new String[]{id}, null);
            int columnIndex = cursor.getColumnIndex(column[0]);
            if (cursor.moveToFirst()) {
                filePath = cursor.getString(columnIndex);
            }
            cursor.close();
        }
    } else {
        filePath = uri.getPath();
    }
    return filePath;
}

Above code return filePath based on SDK version because there are a deferent method to get file path on the latest SDK and older SDK. Once we get filePath we are ready to upload Image.

Step 11. Now once we get original file path we are ready to upload a file using OKHTTP 3 code as shown below

plaintext
public void uploadImage(){

    if(uri == null){
        return;
    }

    final File imageFile = new File(uriToFilename(uri));
    Uri uris = Uri.fromFile(imageFile);
    String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uris.toString());
    String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase());
    String imageName = imageFile.getName();

    //Log.e(TAG, imageFile.getName()+" "+mime+" "+uriToFilename(uri));
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("file", imageName,
                    RequestBody.create(imageFile, MediaType.parse(mime)))
            .build();

    final CountingRequestBody.Listener progressListener = new CountingRequestBody.Listener() {
        @Override
        public void onRequestProgress(long bytesRead, long contentLength) {
            if (bytesRead >= contentLength) {
                if (progressBar != null)
                    MainActivity.this.runOnUiThread(new Runnable() {
                        public void run() {
                            progressBar.setVisibility(View.GONE);
                        }
                    });
            } else {
                if (contentLength > 0) {
                    final int progress = (int) (((double) bytesRead / contentLength) * 100);
                    if (progressBar != null)
                        MainActivity.this.runOnUiThread(new Runnable() {
                            public void run() {
                                progressBar.setVisibility(View.VISIBLE);
                                progressBar.setProgress(progress);
                            }
                        });

                    if(progress >= 100){
                        progressBar.setVisibility(View.GONE);
                    }
                    Log.e("uploadProgress called", progress+" ");
                }
            }
        }
    };

    OkHttpClient imageUploadClient = new OkHttpClient.Builder()
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request originalRequest = chain.request();

                    if (originalRequest.body() == null) {
                        return chain.proceed(originalRequest);
                    }
                    Request progressRequest = originalRequest.newBuilder()
                            .method(originalRequest.method(),
                                    new CountingRequestBody(originalRequest.body(), progressListener))
                            .build();

                    return chain.proceed(progressRequest);

                }
            })
            .build();
    Request request = new Request.Builder()
            .url("Your_Upload_url")
            .header("Accept", "application/json")
            .header("Content-Type", "application/json")
            .post(requestBody)
            .build();


    imageUploadClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            String mMessage = e.getMessage().toString();
            //Toast.makeText(ChatScreen.this, "Error uploading file", Toast.LENGTH_LONG).show();
            Log.e("failure Response", mMessage);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String mMessage = response.body().string();

            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.e(TAG, mMessage);
                    progressBar.setVisibility(View.GONE);
                    upload.setVisibility(View.GONE);
                }
            });
        }
    });
}

Step 12. Now to handle this upload file I am using PHP you can use below code.

plaintext
<?php
    error_reporting(E_ALL);

    $target_path = $_FILES['file']['name'];
    if(move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {
        $msg = "File uploaded successfully!";
    } else{
        $msg = "Sorry, file not uploaded, please try again!";
    }

    $json = ["file" => $_FILES, "response" => $msg];
    header('content-type: application/json');
    echo json_encode($json);
?>

Hope this above code helps you to understand how we can upload a file with progress bar using OkHttp3.

More Stories from

Aneh Thakur
Aneh Thakur.4 min read

React Native 0.78 Unveiled: New Features, Changes, and Benefits You’ll Love 🚀

Discover React Native 0.78! From React 19 support to Android vector drawables and better iOS integration, explore the latest features, changes, and benefits with examples to make app development faster and smoother. 🌟

.
Aneh Thakur
Aneh Thakur.4 min read

🚀 Encore.ts: Blazing Fast Backend Powerhouse – 9x Faster Than Express.js & 3x Faster Than Bun + Zod

Discover why Encore.ts outshines Express.js and Bun + Zod with 9x and 3x faster performance, respectively. Explore sample code, speed benchmarks, and see how this TypeScript framework redefines backend efficiency! ⚡

.
Aneh Thakur
Aneh Thakur.4 min read

Trump Unveils U.S. Crypto Strategic Reserve: Bitcoin and Altcoins Surge

Donald Trump announces a U.S. Crypto Strategic Reserve featuring Bitcoin, Ethereum, XRP, Solana, and Cardano, sparking a $300B market rally. Explore the implications and trends as of March 3, 2025.

.
Aneh Thakur
Aneh Thakur.4 min read

Prototype Your Idea in Under an Hour Using AI

Learn to create working prototypes in under an hour using AI tools like Claude and Bolt. Ideal for designers and entrepreneurs with minimal coding skills.

Aneh Thakur
Aneh Thakur.3 min read

How X’s New Grok AI Tools Make Ad Creation and Analysis a Breeze

Discover X’s latest AI-powered features—Prefill with Grok and Analyze Campaign with Grok. Learn how these tools simplify ad creation, boost campaign performance, and help advertisers save time in 2025.

Built on Koows