I am trying to upload audio file to Speaker Recognition from retrofit but getting the Invalid Audio Error:
please find the code below:
public void createEnrollment(String verficationId,String file) throws IOException {
RequestBody videoBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
MultipartBody.Part vFile = MultipartBody.Part.createFormData("audio", file, videoBody);
ApiInterface service = RetrofitClientInstance.getRetrofitInstance().create(ApiInterface.class);
Call<List<EnrolmentResult>> call = service.postAudioAndGetResponse(API_KEY,verficationId,vFile);
call.enqueue(new Callback<List<EnrolmentResult>>() {
#Override
public void onResponse(Call<List<EnrolmentResult>> call, Response<List<EnrolmentResult>> response) {
Log.d("Result", response.body().toString());
}
#Override
public void onFailure(Call<List<EnrolmentResult>> call, Throwable t) {
//progressDoalog.dismiss();
Log.d("Error", t.getMessage());
}
});
}
public interface ApiInterface {
#Multipart
#POST("identificationProfiles/{verificationProfileId}/enroll")
Call <List<EnrolmentResult>> postAudioAndGetResponse(#Header("Ocp-Apim-Subscription-Key") String keyValue,
#Path("verificationProfileId") String id,
#Part MultipartBody.Part file
);
}
Audio is .wav format and converted to below format:
Container WAV
Encoding PCM
Rate 16K
Sample Format 16 bit
Channels Mono
When i send the same from Post Man i am getting the 202 response as Success
Have you tried using application/json for the media type? ... looks like all calls expect this , even though we are sending binary
Related
I have a list like
[{
Imgstr:"obj as string",
Ingfile:file
},{
Imgstr:"obj as string",
Ingfile:file
}
]
How can I upload them as multipart x if it is a single obj I am sending as multipart body and file
try going to this link and I'll include some of it here:
If this is your first uploading files with Retrofit tutorial, you should visit our uploading files with Retrofit and uploading multiple files tutorials.
In the previous tutorials, we've used various upload options in the FileUploadService class:
public interface FileUploadService {
// previous code for single file uploads
#Multipart
#POST("upload")
Call<ResponseBody> uploadFile(
#Part("description") RequestBody description,
#Part MultipartBody.Part file);
// previous code for multiple files
#Multipart
#POST("upload")
Call<ResponseBody> uploadMultipleFiles(
#Part("description") RequestBody description,
#Part MultipartBody.Part file1,
#Part MultipartBody.Part file2);
}
The second option let's you upload multiple files, but you always have to specify in advance how many. This is difficult when your app doesn't have a fixed number of files and it can vary depending on the use case or user input.
Upload a Dynamic Amount of Files
The solution for this problem is to pass a List or Array of MultipartBody.Part objects. Retrofit and OkHttp will then build an appropriate multipart request with all files. Java arrays or lists allow you to freely add files as required.
Endpoint Declaration
You know the theory, so it's time to look at an example. As always, we'll start with describing the endpoint interface. Of course, this depends on your backend. Make sure your API can handle a random amount of files!
public interface FileUploadService {
#Multipart
#POST("upload")
Call<ResponseBody> uploadMultipleFilesDynamic(
#Part("description") RequestBody description,
#Part List<MultipartBody.Part> files);
}
In the previous examples we carried a description with every request. We'll keep it to show you how it would work, but of course it's only a single description for a lot of files. If you need to also send a dynamic amount of other information, you should check out our tutorial on #PartMap.
The second part of the implementation is using the new endpoint declaration and passing some files. We'll reuse the helper methods from our previous tutorials to simplify creating the necessary multiparts:
#NonNull
private RequestBody createPartFromString(String descriptionString) {
return RequestBody.create(
okhttp3.MultipartBody.FORM, descriptionString);
}
#NonNull
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
// https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
// use the FileUtils to get the actual file by uri
File file = FileUtils.getFile(this, fileUri);
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
// MultipartBody.Part is used to send also the actual file name
return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}
Finally, we'll put everything together to build the upload request:
Uri photoUri = ... // get it from a file chooser or a camera intent
Uri videoUri = ... // get it from a file chooser or a camera intent
// ... possibly many more file uris
// create list of file parts (photo, video, ...)
List<MultipartBody.Part> parts = new ArrayList<>();
// add dynamic amount
if (photoUri != null) {
parts.add(prepareFilePart("photo", photoUri));
}
if (videoUri != null) {
parts.add(prepareFilePart("video", videoUri));
}
// ... possibly add more parts here
// add the description part within the multipart request
RequestBody description = createPartFromString("hello, this is description speaking");
// create upload service client
FileUploadService service = ServiceGenerator.createService(FileUploadService.class);
// finally, execute the request
Call<ResponseBody> call = service.uploadMultipleFilesDynamic(description, parts);
call.enqueue(...);
All of the steps above should be fairly familiar to you. We simply create a part for each file and the description. After everything is put together, we can create a new Call object from our FileUploadService and execute the request as usual.
User can get image from camera and gallery aslo user can crop image and setting in view working good.but after that i want to update it's profile with it's other data like "Name" ,"Number" etc.
by postman image is uploading successfully.
I tried multipart, way sending as file and also try to send as a string but not getting successful or Failure response.i don't know what I m doing wrong. I m new in android please help if you can.
Response and Get Structure
{
"id": 7,
"profile_image": " ImageUrl will come here",
"firstname": "Hamza",
"lastname": "Ali",
"email": "hamzaregardless333#gmail.com",
"contact": "123455666",
"gender": "Male",
"location": "lahore"
}
I don't know where you made a mistake because you didn't share your code.
I'm uploading image like below. Maybe it can help you.
Your Service
public interface YourService {
#Multipart
#POST("api/exampleImageUpload")
Call<YourResponse> uploadImage(
#Part MultipartBody.Part image
);
}
Uploading Image
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://backendapi.com/")
.build();
File file = new File(imagePath);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("paramName","imageName",RequestBody.create(MediaType.parse("multipart/form-data"), file));
YourService iys = retrofit.create(YourService.class);
Call<YourResponse> uploadCall = iys.uploadImage(filePart);
uploadCall.enqueue(new Callback<YourResponse>() {
#Override
public void onResponse(Call<YourResponse> call, Response<YourResponse> response) {
}
#Override
public void onFailure(Call<YourResponse> call, Throwable t) {
}
});
I try to upload an image from an Android App to a Django server using Retrofit 2 and OkHttp3.
For that, I used to create a RequestBody instance using the following lines:
RequestBody requestImageFile =
// NOW this call is DEPRECATED
RequestBody.create(
MediaType.parse("image/*"),
// a File instance created via the path string to the image
imageFile
);
I used the previous instance in the next method call as argument:
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part image = MultipartBody.Part.createFormData("image", imageFile.getName(), requestImageFile);
Finally, I fired up the Retrofit interface to do the rest:
// finally, execute the request
Call<ResponseBody> call = service.upload(image);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.v("Upload", "success");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
Some months ago, Android Studio did not told me that create() was deprecated. When I open the project now, it tells me that create() is deprecated. Does somebody know how to fix it ?
Just swap the parameters from
RequestBody.create(MediaType.parse("image/*"), imageFile);
to
RequestBody.create(imageFile, MediaType.parse("image/*"));
You can use the Kotlin extensions as well.
val requestImageFile = imageFile.asRequestBody("image/*".toMediaTypeOrNull())
Here is how to do it easily with kotlin extension functions from okhttp like:
toRequestBody():
change from :
val requestImageFile = RequestBody.create(
MediaType.parse("image/*"),
imageFile
);
to this:
val requestImageFile = imageFile.toRequestBody(MediaType.parse("image/*"))
'
more info here: https://square.github.io/okhttp/upgrading_to_okhttp_4/
You can change from:
RequestBody.create(MediaType.parse("image/*"), imageFile);
to:
RequestBody.Companion.create(imageFile, MediaType.parse("image/*"))
I'm trying to upload an image from Android Studio to Laravel server using Retrofit2 Multipart encoding, but i keep getting "500 Internal Server Error", which means something is going wrong server-side probably, but i can't pin what it is.
this is my interface call (Android Studio):
#Multipart
#POST("public/imagem")
Call<ResponseBody> uploadImagem(#Part MultipartBody.Part part,
#Part("name") RequestBody name,
#Part("animal_id") long animal_id,
#Part("ativo") int ativo);
this is the request (Android Studio):
//Create a file object using file path
File file = new File(filePath);
// Create a request body with file and image media type
RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
// Create MultipartBody.Part using file request-body,file name and part name
MultipartBody.Part part = MultipartBody.Part.createFormData("upload", file.getName(), fileReqBody);
//Create request body with text description and text media type
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "image-type");
WebService.getInstance().getService().uploadImagem(part, name, animal_id, 1).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
//THIS IS WHERE I WANT TO GET
} else {
//THIS IS WHERE IM GETTING AT EVERYTIME
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
this is my route (Laravel):
Route::post('imagem','ImagemController#createImagem');
this is the "createImagem" function inside "ImagemController" (Laravel):
public function createImagem(Request $request){
$destinationPath = url('/midia'); //i have a "midia" folder inside "public" folder
$image = $request->file('part');
$name = $request->input('name');
$image->move($destinationPath, $name);
$dbPath = $destinationPath. '/'.$name;
$imagem = new Imagem();
$imagem->animal_id = $request->input('animal_id');
$imagem->img_url = $dbPath;
$imagem->ativo = $request->input('ativo');
$imagem->save();
return response()->json($imagem);
}
and these are the attributes inside "Imagem" table and their types:
but i'm getting 500 Internal Server Error, so probably something server-side isn't according to what would be right logically, can you help me find what is wrong in my code?
ps. I do have other requests to this server that are fully functional, but all of them are just fields, while this has a file, which needs Multipart encoding, unlike the others.
EDIT:
This is the server error log:
[2019-06-11 21:21:03] local.ERROR: Call to a member function move() on null {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function move() on null at /.../Controllers/ImagemController.php:28)
So it seems i am unable to get file with
$image = $request->file('part');
I think the error could be because path must to be a path and not an url:
$destinationPath = url('/midia');
If you want to move the file to public folder, you have to use public_path() for the path:
$image = $request->file('part');
$destinationPath = 'midia';
$name = $request->input('name') .'.'. $image->getClientOriginalExtension();
$image->move(public_path($destinationPath), $name);
If you want to avoid the error and not waste server resources when there is no image in the request, add a validation at the start of your function:
public function createImagem(Request $request){
$this->validate($request, [
'part' => 'required|image|max:2048',
// other fields validations
]);
// the createImagem logic here
}
if the validation fails, you will not try to move the file and will not query DB either, then the proper error response will automatically be sent back to the client where you can handle it.
try this code hope its helpfull for you.
#Multipart
#POST("public/imagem")
Call<ResponseBody> uploadImagem(#Part MultipartBody.Part part);
if you are using key part
$image = $request->file('part');
also use that key "part" in java code
Uri uri1 = Uri.parse(event_image);
File file = new File(uri1.getPath());
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part image = MultipartBody.Part.createFormData("part", file.getName(), reqFile);
mService.addEvent(image).enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
}
});
I have an image on a server stored in a file (not db). I want to display this image in a layout view in Android Studio. I am using Web API2 and retrofit to exchange data.
Using retrofit, I know I need to send the file encapsulated in a class. I am not aware of what type to create? (Byte array?) and how retrofit on the android side would convert this type. I have tried to use byte[] on boths side however retrofit was not able to read the byte[] from Json.
Would anyone be able to guide me on how I would go about transferring this jpeg image? Thanks!
I've recently implemented it.
This is the method in my api.
[HttpPost]
public IHttpActionResult Upload()
{
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
// Do something with file.
}
else
{
// No files.
}
}
The class you are looking for is retrofit's TypedFile class.
This is my implementation.
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint("baseurl").build();
ApiTaqueria api = restAdapter.create(ApiTaqueria.class);
TypedFile foto = new TypedFile("multipart/form-data", new File("path"));
api.subirLogoTaqueria(foto, new Callback<Taqueria>() {
#Override
public void success(Taqueria result, Response response) {
// Do something.
}
#Override
public void failure(RetrofitError retrofitError) {
// Do something.
}
});
In the retrofit interface.
#Multipart
#POST("/api/Photo/Upload")
public void subirLogoTaqueria(#Part("foto") TypedFile foto, Callback<Taqueria> callback);
Happy coding.