POST file(image with multipart/form-data) with form-data in android
Use retrofit for multipart content. It is lightning fast.
Write the following in APInterface , add photo MultiPart body and all other params in string RequestBody
@Multipart
@POST("MethodName")
Call<Response> updateUser(@Part MultipartBody.Part photo,
@Part("string") RequestBody string);
these lines in ApiClient
public static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build();
public static Retrofit getClient() {
Retrofit retrofit = new Retrofit.Builder().baseUrl("url").addConverterFactory(GsonConverterFactory.create()).client(okHttpClient).build();
return retrofit;
}
Send your file to server using these Multipart retrofit technique in your activity.
//path is the file path
File image = new File("" + (String) path);
RequestBody requestFile =
RequestBody.create(MediaType.parse(MULTIPART_FORM_DATA), image);
MultipartBody.Part fileImage = null;
if (requestFile.contentLength() != 0)
fileImage = MultipartBody.Part.createFormData("file", image.getName(), requestFile);
and send that file using retrofit call it will work.
POST Multipart Form Data using Retrofit 2.0 including image
I am highlighting the solution in both 1.9 and 2.0 since it is useful for some
In 1.9
, I think the better solution is to save the file to disk and use it as Typed file like:
RetroFit 1.9
(I don't know about your server-side implementation) have an API interface method similar to this
@POST("/en/Api/Results/UploadFile")
void UploadFile(@Part("file") TypedFile file,
@Part("folder") String folder,
Callback<Response> callback);
And use it like
TypedFile file = new TypedFile("multipart/form-data",
new File(path));
For RetroFit 2 Use the following method
RetroFit 2.0 ( This was a workaround for an issue in RetroFit 2 which is fixed now, for the correct method refer jimmy0251's answer)
API Interface:
public interface ApiInterface {
@Multipart
@POST("/api/Accounts/editaccount")
Call<User> editUser(@Header("Authorization") String authorization,
@Part("file\"; filename=\"pp.png\" ") RequestBody file,
@Part("FirstName") RequestBody fname,
@Part("Id") RequestBody id);
}
Use it like:
File file = new File(imageUri.getPath());
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"),
file);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"),
firstNameField.getText()
.toString());
RequestBody id = RequestBody.create(MediaType.parse("text/plain"),
AZUtils.getUserId(this));
Call<User> call = client.editUser(AZUtils.getToken(this),
fbody,
name,
id);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(retrofit.Response<User> response,
Retrofit retrofit) {
AZUtils.printObject(response.body());
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
Uploading image to server in Multipart along with JSON data in Android
/**
* This utility function will upload the file to the Url
* * @param filePath - absolute path of the file to be uploaded
* @param postUrl - Remote Url where the file need to be posted
* @param contentType - content-type of the uploaded file
* @throws Exception
*/
public static void postFile(String filePath, String postUrl,
String pictureTitleStr, String pseudoTextStr)
throws Exception {
String url = postUrl;
HttpURLConnection conn = null;
final String CrLf = "\r\n";
JSONObject json = new JSONObject();
int bytesRead = 0;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "xxxxxxxx";
String EndBoundary = "";
int maxBufferSize = 1 * 1024 * 1024;
HttpResponse response = null;
// Having HttpClient to respond to both HTTP and HTTPS url connection by accepting the urls along with keystore / trust certificates
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUserAgent(params, "YourAppName/1.1");
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
HttpConnectionParams.setSoTimeout(params, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
HttpClientParams.setRedirecting(params, false);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
mHttpClient = new DefaultHttpClient(ccm, params);
} catch (Exception e) {
}
String base64EncodedCredentials = Base64.encodeToString((userName + ":" + password).getBytes("US-ASCII"),
Base64.DEFAULT);
System.out.println("Encoded Credit " + base64EncodedCredentials);
json.put("pseudo", pseudoTextStr);
json.put("title", pictureTitleStr);
String jsonStr = json.toString();
// System.out.println("JSON VALUE " + jsonStr);
URL url2 = new URL(postUrl);
Bitmap bm = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 25, baos); // bm is the bitmap object
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
String str = twoHyphens + boundary + lineEnd;
String str2 = "Content-Disposition: form-data; name=\"jsonFile\"";
String str3 = "Content-Type: application/json";
String str4 = "Content-Disposition: form-data; name=\"imgName\"";
String str5 = "Content-Type: image/jpeg";
String str6 = twoHyphens + boundary + twoHyphens;
String StrTotal = str + str2 + "\r\n" + str3 + "\r\n" +"\r\n" + jsonStr + "\r\n" + str
+ str4 + "\r\n" + str5 + "\r\n"+"\r\n"+ encodedImage + "\r\n" + str6;
//System.out.print("Multipart request string is "+StrTotal);
HttpPost post = new HttpPost(postUrl);
post.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials(
userName, password), "UTF-8", false));
post.addHeader("Content-Type","multipart/form-data;boundary="+boundary);
// System.out.println("Sending Post proxy request: " + post);
StringEntity se = new StringEntity(StrTotal);
se.setContentEncoding("UTF-8");
post.setEntity(se);
response = mHttpClient.execute(post);
/* Checking response */
statusCode = response.getStatusLine().getStatusCode();
System.out.println("Http Execute finish " + statusCode);
HttpEntity entity = response.getEntity();
String getResponseText = entity.toString(); // EntityUtils.toString(entity);
System.out.println(" Post Response Text from Server : "
+ getResponseText);
}
Uploading a File (Multipart/Form data) to Server Failed in Android using ion library
Well i have found out a simple way of uploading or posting multipart/form-data with an upload progress bar. may be this could help.
Suppose you server is waiting for the following data :
1.File(PDF,Image,Audio,Video etc.).
2.Name
3.Email
4.Address.
and you want to upload that information once in a URL be it an Absolute URL or a Relative URL, ion library is easy , precise, efficient and much better in this.
STEP 1:
declare your URI
private Uri filePath;
STEP 2:
then Pick the file from your gallery , here it's your choice you identify any kind of files you want a user to view, me here i have identified a PDF file.
on this line intent.setType("application/pdf");
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("application/pdf");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Pdf"), PICK_PDF_REQUEST);
}
//handling the image chooser activity result
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PDF_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
Toast.makeText(getApplicationContext(), "" + filePath, Toast.LENGTH_LONG).show();
}
}
then you can call showFileChooser()
in the Button
for a click to access your gallery.
STEP 3:
a) Make a method Upload()
containing ion library to start the job. If you see in this method , i first declared the file,name, email,address
, for file
it gets the URI data of a selected file or the path file , then name, email,address
, it gets the data from EditText , you have to declare EditText to get the data.
b) Then identify the URL you want to use in Posting
mine is url_
. but make sure you include POST
, in the load section .load("POST",url_)
.
c) Then you set the file by using .setMultipartFile("File", file)
and the rest of the parameters by setting MultipartParameter .setMultipartParameter("Name", name)
and so on.
public void Upload() {
String file= FilePath.getPath(this, filePath);
final String name = name_edt.getText().toString();
final String email = email_edt.getText().toString();
final String address = address_edt.getText().toString();
final ProgressDialog pd;
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Logging in...");
pd.setCancelable(false);
pd.show();
final String url_ = "xxxxxxxxxxxxxxx";
final File file = new File(Uri.parse(path).toString());
Ion.with(MainActivity.this)
.load("POST",url_)
.progressDialog(pd)
.setMultipartFile("file", file)
.setMultipartParameter("Name", name)
.setMultipartParameter("Email", email)
.setMultipartParameter("Address.", address)
.asString()
.setCallback(new FutureCallback<String>() {
@Override
public void onCompleted(Exception e, String result) {
// Toast.makeText(getApplicationContext(),""+file,Toast.LENGTH_LONG).show();
System.out.println("Error " + e);
// Toast.makeText(getApplicationContext(), "Exception : " + e, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
// Toast.makeText(getApplicationContext(),""+e,Toast.LENGTH_LONG).show();
pd.dismiss();
}
});
}
Then you are good to go , according to your C# API , the file will be able to save in the Folder. Even others use Php
or any other language you can create your own Api to save a file in your server folder
Hope it works well.
Retrofit 2 Multipart image upload with data
We test api in Postman... So my Create Post Answer includes (all Dynamic)
- Headers
- Simple Strings
- Single Image
- Array Of Images
- Array Of Categories
- Array Of Features
Almost all things
Below is the Postman image for api testing...
- Headers Image
So for this ...
Below is my Api...
@POST("post-create")
Call<PostCreateResponse> getPostCreateBodyResponse(
@Header("Accept") String accept,
@Header("Authorization") String authorization,
@Body RequestBody file
);
Now Retrofit Client area--->
private Retrofit retrofit;
// This is Client
private RetrofitClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout(100, TimeUnit.SECONDS);
httpClient.readTimeout(100,TimeUnit.SECONDS);
httpClient.writeTimeout(100,TimeUnit.SECONDS);
httpClient.addInterceptor(logging); // <-- this is the important line!
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
This is the way I Made the Request...
/*
* -------------- Retrofit post Create single featured Image Working with MultipartBody -----------
* */
progressDialog.show();
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("title", "3 room Current Free")
.addFormDataPart("location", "Dhaka")
.addFormDataPart("latitude", "23.7515")
.addFormDataPart("longitude", "90.3625")
.addFormDataPart("condition", "1")
.addFormDataPart("rent_amount", "123456")
.addFormDataPart("is_negotiable", "0")
.addFormDataPart("available_from", "2018-10-15");
// Categories
for (int categoryId : categories) {
builder.addFormDataPart("categories[]", String.valueOf(categoryId));
}
// Features
for (Integer featureId : features) {
builder.addFormDataPart("features[]", String.valueOf(featureId));
}
// featured Image
if (photoPaths.get(0) != null) {
File featured_image = new File(photoPaths.get(0));
if (featured_image.exists()) {
// If you want to use Bitmap then use this
Bitmap bmp = BitmapFactory.decodeFile(featured_image.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);
builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, bos.toByteArray()));
// If you want to use direct file then use this ( comment out the below part and comment the above part )
//builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, featured_image));
}
}
// Images
for (String photoPath : photoPaths) {
if (photoPath != null) {
File images = new File(photoPath);
if (images.exists()) {
builder.addFormDataPart("images[]", images.getName(), RequestBody.create(MultipartBody.FORM, images));
}
}
}
RequestBody requestBody = builder.build();
Call<PostCreateResponse> call = RetrofitClient.getInstance().getApi().getPostCreateBodyResponse(Accept, Authorization, requestBody);
call.enqueue(new Callback<PostCreateResponse>() {
@Override
public void onResponse(Call<PostCreateResponse> call, Response<PostCreateResponse> response) {
progressDialog.dismiss();
Log.d(TAG, "onResponse: response code: retrofit: " + response.code());
}
@Override
public void onFailure(Call<PostCreateResponse> call, Throwable t) {
}
});
/*
* ---------------- Retrofit post Create single featured Image Working with MultipartBody----------------
* */
I hope this will help you all... thanks
Related Topics
Eclipse Indigo - Cannot Install Android Adt Plugin
Android How to Create Triangle and Rectangle Shape Programmatically
Android: How to Get Gsm Signal Strength for All Available Network Operators
Importing Jar Libraries into Android-Studio
Error:(9, 5) Error: Resource Android:Attr/Dialogcornerradius Not Found
Failure [Install_Failed_Invalid_Apk]
Android Gridview Draw Dividers
Using Notifyitemremoved or Notifydatasetchanged with Recyclerview in Android
Android: How to Create a Motionevent
Android Quotes Within an SQL Query String
Java.Lang.Securityexception: !@Too Many Alarms (500) Registered from Pid 10790 Uid 10206
Android: Making a Fullscreen Application
Rate Google Play Application Directly in App
How to Check If an App Is a Non-System App in Android
Can't Upgrade Android Sdk Tools