Ir al contenido principal

How to upload File from form data POST in Android with Retrofit 2

 The last day I explain how to upload a simple CSV file using node. And now I teach how to upload from android device.

Get source code here:  GitHub

This article is write in java... later I'll add the method for kotlin. The logic is not changed, only the format code.

1) Is necessary add the dependencies in gradle: module

implementation 'com.google.code.gson:gson:2.8.6'
// RETROFIT //
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'

2) Add permissions in AndroidManifest.xml and modified the application for work with network security policy

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


in applitacion add this for work with HTTP
android:usesCleartextTraffic="true"

3) Add all code necessary for request any permission for write or read the memory card (you can use the traditional system for request permission or use contract). I worked directly in MainActivity and added a button to test my app

private final int PERMISSION = 100;
private final String[] permissions = {
	Manifest.permission.WRITE_EXTERNAL_STORAGE,
	Manifest.permission.READ_EXTERNAL_STORAGE
};
private Button btn;
private ProgressBar progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	btn = (Button) findViewById(R.id.button);
	progressBar = (ProgressBar) findViewById(R.id.progressBar);
	progressBar.setVisibility(View.GONE);
	verificPermission();
}

public void send(View v) {
	btn.setEnabled(false);
	progressBar.setVisibility(View.VISIBLE);
	initialize(); // in this point, this method is not exist
}

private void verificPermission() {
	if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
		showPermissionRequest();
	}
}

private void showPermissionRequest() {
	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	builder.setTitle("Information");
	builder.setMessage("Next, a dialog box will be shown where you will be asked to authorize the media handling permissions, please accept them so that the application can continue working properly ...");
	builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {
			getPermissions();
		}
	});
	builder.setCancelable(false);
	builder.show();
}

private void getPermissions() {
	ActivityCompat.requestPermissions(this, permissions, PERMISSION);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
	super.onRequestPermissionsResult(requestCode, permissions, grantResults);
	if(requestCode == PERMISSION) {
		showMessage("permissions granted");
	}
}

private void showMessage(String message) {
	message = (message.isEmpty()) ? "There is no message to show" : message;
	Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}

4) Create a class singlenton for retrofit Instance

public class RetrofitInstance {
    private static Retrofit retrofit;
    private static final String BASE_URL = "http://192.168.0.160:3000"; // this IP is changed for your IP

    public static Retrofit getInstance() {
        final OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.MINUTES)
                .writeTimeout(1,TimeUnit.MINUTES)
                .readTimeout(1,TimeUnit.MINUTES)
                .build();
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        }
        return retrofit;
    }
}

5) Create a interface for upload the file from form data (multipart) POST

public interface RetrofitServices {

    @Multipart
    @POST("upload/")
    Call<CSVUploadResponse> uploadAttachment(@Part MultipartBody.Part filePart);

}

6) Create a simple class for read the response message (change this class is not using my project node for upload file

public class CSVUploadResponse {

    @SerializedName("message")
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

7) Implements these method in MainActivity, I created a ExportCSVFaker for generate a simple file for upload (this code is in GitHub)

private void initialize() {
	ExportCSVFaker exportCSVFaker = new ExportCSVFaker(this);
	if(exportCSVFaker.isCSVExist()) {
		sendCSVToServer(exportCSVFaker.getCsv());
	} else {
		showMessage("The file was not generated");
	}
}

private void sendCSVToServer(File csv) {
	MultipartBody.Part filePart = MultipartBody.Part.createFormData(
			"uploadFile",
			csv.getName(),
			RequestBody.create(MediaType.parse("text/plain" + "; charset=utf-8"), csv)
	);
	RetrofitServices retroServices = RetrofitInstance.getInstance().create(RetrofitServices.class);
	Call<CSVUploadResponse> responseCall = retroServices.uploadAttachment(filePart);

	responseCall.enqueue(new Callback<CSVUploadResponse>() {
		@Override
		public void onResponse(Call<CSVUploadResponse> call, Response<CSVUploadResponse> response) {
			showMessage(response.message());
			setVisibilityElements();
		}

		@Override
		public void onFailure(Call<CSVUploadResponse> call, Throwable t) {
			t.printStackTrace();
			showMessage("The upload is failed");
			setVisibilityElements();
		}
	});
}

private void setVisibilityElements() {
	btn.setEnabled(true);
	progressBar.setVisibility(View.GONE);
}

The magic is in the method "sendCSVToServer" and the parameter of type File for send to server using the class "MultipartBody.Part" for add to "responseCall"

The result is the next

That's folks

Comentarios

Entradas populares de este blog

Northwind para Mysql y otras

Supongamos que necesitamos una base de datos para comenzar a hacer pruebas y a la vez necesitamos que esa base de datos contenga mucha información con la cual trabajar. En mis tiempos de universidad existía una base de datos que utilizábamos en los laboratorios con SQL Server y c# para mostrar los datos en algún formulario. El nombre era Northwind. El problema es que era solo para SQL Server, pero alguien en se dio a la tarea de exportar esa base de datos a MySql y es justo lo que te vengo a mostrar acá. Hace un tiempo atrás clone de los repositorios de Google Code   esa información (que como algunos de ustedes sabrá dejara de estar al servicio de todos en un tiempo). Modifique un poco la DB de Mysql para que se pudiera ejecutar el script sin ningún problema. Lo interesante de todo esto es que puedes utilizar los demás script para diferentes gestores de base de datos Se advierte que para poder usarlas adecuadamente hay que modificar los campos de tipo longblob y qu...

Instalacion de apk desde el adb (Linux y Windows)

Por lo general siempre instalamos nuestras aplicaciones por medio de algún gestor oh tienda de aplicaciones como el Google Play oh F-Droid por mencionar a algunos. Pero que pasa cuando no podemos acceder a esas tiendas y hemos modificado algunas cosas del sistema como por ejemplo la eliminación del teclado, por el simple hecho de que no nos gusta, oh a ver quitado el propio launcher del sistema, aunque suene ilógico hay personas que lo hacen (yo por ejemplo lo he hecho a modo de prueba en un Kiosera que tuve, ya que me pareció demasiado pesado y lelo el launcher y el teclado por defecto y llegue a una optimizacion del SO de un 100%). Quizás eso es lo mejor de Android, el completo control que este te da si eres root, sin mas preámbulo te muestro como instalar las apk por medio del ADB de Android. Pero antes de que los vea me gustaría aclarar que esto es aplicable tanto para dispositivos físicos como emuladores, en el caso de ser dispositivos físicos asegúrate de tener los dr...