How to use Android WorkManager to upload image in background

In this android programming source code example, we are going to use Android WorkManager to upload image in background.

You can copy and adopt this source code example to your android project without reinventing the wheel.

Below is a step by step source code to use Android WorkManager to upload image in background.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"    tools:context=".WorkManagerAndJobSchedule.WorkManagerAndJobScheduleActivity13">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp">

        <Button
            android:id="@+id/pickpicture"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:text="Pick Picture"
            android:textAllCaps="false"
            android:textColor="#ffffff"
            android:textSize="19sp"/>

        <Button
            android:id="@+id/upload"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:text="Upload"
            android:textAllCaps="false"
            android:textColor="#ffffff"
            android:textSize="19sp"
            android:layout_marginTop="10dp"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.util.concurrent.TimeUnit;

public class WorkManagerAndJobScheduleActivity13 extends AppCompatActivity {
    private Button pickpicture;
    private Button upload;
    private String imagePathUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_work_manager_and_job_schedule13);
        pickpicture = (Button) findViewById(R.id.pickpicture);
        upload = (Button) findViewById(R.id.upload);
        pickpicture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/png image/jpeg image/gif");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Select Image From Gallery"), 1);

            }
        });

        upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startWork();
            }
        });
    }

    private void startWork(){
        OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(WorkManager13.class)
                .setInputData(createInputData(imagePathUri))
                .setInitialDelay(2, TimeUnit.SECONDS).build();
        WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
    }

    //result is been return here
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case(1): {
                if (resultCode == RESULT_OK && data != null && data.getData() != null) {
                    Uri uri = data.getData();
                    try {
                        String pathToStoredMedia = getRealPathFromURIPath(uri, WorkManagerAndJobScheduleActivity13.this);
                        imagePathUri = pathToStoredMedia;
                        Toast.makeText(WorkManagerAndJobScheduleActivity13.this, "Image pick successfully", Toast.LENGTH_LONG).show();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;
            }
        }
    }

    private Data createInputData(String imagePath){
        Data data = new Data.Builder()
                .putString("imagePath", imagePath)
                .build();
        return data;
    }

    //geting real path from gallery
    private String getRealPathFromURIPath(Uri contentURI, Activity activity) {
        Cursor cursor = activity.getContentResolver().query(contentURI, null, null, null, null);
        if (cursor == null) {
            return contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            return cursor.getString(idx);
        }
    }

}

WorkManager13.java

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import com.google.gson.annotations.SerializedName;

import java.io.File;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

public class WorkManager13 extends Worker {
    public WorkManager13(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String imagePath = getInputData().getString("imagePath");
        //Defining retrofit api service
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://local ip address/test/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        File file = new File(imagePath);
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
        MultipartBody.Part fileupload = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
        RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), file.getName());
        ApiService service = retrofit.create(ApiService.class);
        Call<PostResponse> call = service.postData(fileupload, filename);
        //calling the api
        call.enqueue(new Callback<PostResponse>() {
            @Override
            public void onResponse(Call<PostResponse> call, Response<PostResponse> response) {
                if(response.isSuccessful()){
                    showNotification("Inducesmile", "Image uploaded successfully");
                }
            }

            @Override
            public void onFailure(Call<PostResponse> call, Throwable t) {
                Result.failure();
            }
        });
        return Result.success();
    }

    private void showNotification(String title, String task){
        NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        if(Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
            NotificationChannel notificationChannel = new NotificationChannel("inducesmile", "inducesmile", NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(notificationChannel);
        }
        NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(),"inducesmile")
                .setContentTitle(title)
                .setContentText(task)
                .setSmallIcon(R.mipmap.ic_launcher);
        notificationManager.notify(1, notification.build());
    }

    private interface ApiService {
        @Multipart
        @POST("index.php")
        Call<PostResponse> postData(
                @Part MultipartBody.Part file,
                @Part("name") RequestBody name);
    }

    private class PostResponse{
        @SerializedName("success")
        private String success;

        public void setSuccess(String success){
            this.success = success;
        }
        public String getSuccess(){
            return success;
        }
    }

}

create new index.php in your localhost(e.g wamp server) then copy below code.

index.php

<?php
if(isset($_FILES['file']['name'])){
    $result = array("success" => $_FILES['file']['name']);
    $file_path = basename($_FILES['file']['name']);
    if(move_uploaded_file($_FILES['file']['tmp_name'], $file_path)){
        $result = array("success" => "file uploaded");
    }else{
        $result = array("success" => "failed");
    }
}else{
    $result = array("success" => "No file received");
}
echo json_encode($result, JSON_PRETTY_PRINT);
?>

app/build.gradle

implementation 'androidx.work:work-runtime:2.1.0-beta02'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

If you have any question or suggestions kindly use the comment box or you can contact us directly through our contact page below.

Add a Comment