I am recently developing new android project. I am trying to save image files into the server directory.
I use Retrofit for HttpConnection with server.
Storing image files into the server directory works well, but the image is not available. Everytime I upload files into the server, it says An error occurred while loading the image. I have been looking for solutions and trying to fix this problem, but I have no idea what causes this problem.
Here is my android code :
ArrayList<MultipartBody.Part> files = new ArrayList<>();
for(int a = 0; a < list.size(); a++) {
// list = uri image list for recyclerview.
RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), String.valueOf(list.get(a)));
String fileName = "photo" + a + ".jpg";
MultipartBody.Part filePart = MultipartBody.Part.createFormData("uploaded_file"+a, fileName, fileBody);
files.add(filePart);
}
Call<String> uploadPost = posts.uploadPost(files,hashMap);
uploadPost.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful() && response.body() != null) {
Intent intent = new Intent(upload_sale.this, MainActivity.class);
startActivity(intent);
finish();
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("upload_post",t.getMessage());
}
});
Here is the php code :
$authNum = $_POST['authNum'];
$title = $_POST['title'];
$des = $_POST['description'];
$price = $_POST['price'];
$area = $_POST['area'];
$longitude = $_POST['longitude'];
$latitude = $_POST['latitude'];
$count = $_POST['count'];
$count_int = (int)$count;
if(isset($_FILES['uploaded_file0']['name'])) {
for($i = 0; $i<$count_int; $i++) {
$basename = basename($_FILES['uploaded_file'.$i]['name']);
$file_path = $file_path . $basename;
if(isset($_FILES['uploaded_file'.$i])) {
move_uploaded_file($_FILES['uploaded_file'.$i]['tmp_name'],"./postImage/".$fn.$basename);
$query_img =
"INSERT INTO post_img(path,authNum,img_del,post_authNum)
VALUES ('http://3.36.34.173/postImage/".$fn.$basename."',$authNum,'../postImage/".$fn.$basename."','$post_authNum')
";
}
Thank you in advance.enter image description here
Related
I have a class that add a news with its images by Retrofit.
When Retrofit wants upload images, it shows me this error: FileNotFoundException
I have seen similar questions and answers but nothing was with multiple images.
So I could not find my solution and ask this question.
This is my Retrofit interface's method:
#POST("News/SaveNews")
Call<GetResualt> setNewsLetter(#Body NewsLetterModel newsLetter);
#Multipart
#POST("Products/Post")
Call<GetResualt> uploadNewsLetterImage(#Query("ProductID") String newsLetterId,
#Query("CompanyID") String coId,
#Query("UserID") String uID,
#Query("Token") String token,
#Part List<MultipartBody.Part> files);
This is my onActivityResult after image selecting:
ActivityResultLauncher<Intent> mLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK) {
if (result.getData() != null) {
if (result.getData().getClipData() != null) {
int count = result.getData().getClipData().getItemCount();
int currentItem = 0;
while (currentItem < count) {
Uri imageUri = result.getData().getClipData().getItemAt(currentItem).getUri();
imageUriList.add(imageUri);
partNames.add(currentItem + "");
currentItem++;
}
} else if (result.getData().getData() != null) {
imageUriList.add(result.getData().getData());
}
}
NewsLetterModel newsLetter = new NewsLetterModel();
newsLetter.setActiveComment(false);
newsLetter.setActiveLike(false);
newsLetter.setActiveSave(false);
newsLetter.setCategory(category);
newsLetter.setCompanyId(BaseCodeClass.CompanyID);
newsLetter.setCreatorId(BaseCodeClass.userID);
newsLetter.setLinkOut("");
newsLetter.setLinkToInstagram("");
newsLetter.setNewsDescription(description);
newsLetter.setNewsTitle(title);
newsLetter.setShow(true);
newsLetter.setSpare1("#FFFFFF");
newsLetter.setSpare2("#FFFFFF");
newsLetter.setSpare3("#FFFFFF");
newsLetter.setToken(BaseCodeClass.token);
newsLetter.setUserId(BaseCodeClass.userID);
uploadNewsLetter(newsLetter);
}
}
);
This is uploadNewsLetter():
private void uploadNewsLetter(NewsLetterModel newsLetter) {
Retrofit retrofit;
JsonApi api;
retrofit = RetrofitInstance.getRetrofit();
api = retrofit.create(JsonApi.class);
Call<GetResualt> call = api.setNewsLetter(newsLetter);
call.enqueue(new Callback<GetResualt>() {
#Override
public void onResponse(Call<GetResualt> call, Response<GetResualt> response) {
if (response.body().getResualt().equals("100")) {
String newsId = response.body().getMsg();
List<MultipartBody.Part> files;
files = convertUriToFIle(partNames, imageUriList);
uploadNewsImages(newsId, files);
}
}
#Override
public void onFailure(Call<GetResualt> call, Throwable t) {
Log.e("Error", t.getMessage());
}
});
}
This is convertUriToFIle()
private List<MultipartBody.Part> convertUriToFIle(List<String> partNames, List<Uri> imageUriList) {
List<MultipartBody.Part> files = new ArrayList<>();
for (int i = 0; i < imageUriList.size(); i++) {
File file = new File(imageUriList.get(i).getPath());
RequestBody requestFile = RequestBody.create(MediaType.parse(FileUtils.MIME_TYPE_IMAGE), file);
files.add(MultipartBody.Part.createFormData(partNames.get(i), file.getName(), requestFile));
}
return files;
}
And This is uploadNewsMessage:
private void uploadNewsImages(String newsLetterId, List<MultipartBody.Part> files) {
Retrofit retrofit;
JsonApi api;
retrofit = RetrofitInstance.getRetrofit();
api = retrofit.create(JsonApi.class);
Call<GetResualt> call = api.uploadNewsLetterImage(newsLetterId, BaseCodeClass.CompanyID, BaseCodeClass.userID, BaseCodeClass.token, files);
call.enqueue(new Callback<GetResualt>() {
#Override
public void onResponse(Call<GetResualt> call, Response<GetResualt> response) {
if (response.body().getResualt().equals("100")) {
Toast.makeText(getContext(), "خبر با موفقیت ثبت شد", Toast.LENGTH_SHORT).show();
} else {
Log.e("Error", response.body().getResualt() + " " + response.body().getMsg());
}
}
#Override
public void onFailure(Call<GetResualt> call, Throwable t) {
Log.e("Error", t.getMessage());
}
});
}
So base on my code, at first application uploads news and other stuffs except of images, after that it uploads images.
But when it wants upload images it goes to onFailur of retrofit and shows me this error: FileNotFoundException.
In convertUriToFIle() use FileUtils.getFile(context,uri) instead of new File(imageUriList.get(i).getPath());
I am trying to send multiple files(images) in gmail but i am not able to send it. I have tried putting the multipart in array but instead of going files in a single mail, two mails are being delivered. My code is as below:
Interface:
public interface EmailService {
#Multipart
#POST("/send/email")
Call<OnlineAushadiModel> sendEmailOnlineAushadi(
#Part("FROM") RequestBody requestFrom,
#Part("TO") RequestBody requestTo,
#Part("SUBJECT") RequestBody requestSubject,
#Part("MailContain") RequestBody requestMailContain,
#Part("FileName") RequestBody requestFileName,
}
The main Activity:
private void sendData(HashMap<Integer, String> buttons) {
Date today = Calendar.getInstance().getTime();
to = RequestBody.create(MediaType.parse("text/plain"), "to");
from = RequestBody.create(MediaType.parse("text/plain"), "bajracharyasudeep#gmail.com");
subject = RequestBody.create(MediaType.parse("text/plain"), "You have received a new Order.");
content = RequestBody.create(MediaType.parse("text/plain"),
"Name: " + HomeActivity.username + "\n" +
"Contact Number: " + HomeActivity.phoneNumber + "\n" +
"Order date and Time: " + today + "\n" +
"Address For Delivery: " + etDeliveryAddress.getText().toString());
fileName = RequestBody.create(MediaType.parse("text/plain"),"hello");
fileToUpload = new MultipartBody.Part[buttons.size()];
for(int i = 0; i<buttons.size();i++){
Log.e("btnValue", buttons.get(i) + "");
File file = new File(buttons.get(i));
RequestBody mFile = RequestBody.create(MediaType.parse("image/" + fileExtension), file);
fileToUpload[i] = MultipartBody.Part.createFormData("file", file.getName(), mFile);
emailService = ApiClient.getApiClientOnlineAushadi().create(EmailService.class);
Call<OnlineAushadiModel> fileUpload = (Call<OnlineAushadiModel>) emailService.sendEmailOnlineAushadi(to,from,subject,content,fileName,fileToUpload[i]);
fileUpload.enqueue(new Callback<OnlineAushadiModel>() {
#Override
public void onResponse(Call<OnlineAushadiModel> call, Response<OnlineAushadiModel> response) {
Toast.makeText(getActivity(), "Success " + response.message(), Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Call<OnlineAushadiModel> call, Throwable t) {
Log.e("error",t.getMessage() + "");
}
});
}
I have tried other methods such as putting the api call out of the loop but it still didnot helped. Can anybody please help me to send multiple files in Multipart?
You should not upload the file in the loop. Like the code example!
private void CallAPI() {
boolean HaveFile;
final ProgressDialog pd = new ProgressDialog(this);
pd.setMessage("Uploading...");
pd.setCancelable(false);
pd.show();
ArrayList<MultipartBody.Part> body = new ArrayList<>();
//image path is a string list of seleted files path
if (imagePath.size() != 0) {
for (int i = 0; i < imagePath.size(); i++) {
//creating a file
File file = new File(imagePath.get(i));
//creating request body for file
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
body.add(MultipartBody.Part.createFormData("uploaded_file", file.getName(), requestFile));
}
HaveFile=true;
} else {
RequestBody attachmentEmpty = RequestBody.create(MediaType.parse(/*"multipart/form-data"*/"text/plain"), "");
body.add( MultipartBody.Part.createFormData(/*"uploaded_file"*/"attachment", "0736E389-EF21-4286-BEBF-14CCD48B04A6", attachmentEmpty));
HaveFile=false;
}
APIService service =
ServiceGenerator.getclient().create(APIService.class);
Call<String> call = service.uploadMulFiles(body.size() == 0 ? null : body ,to,from,subject,content,fileName);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(#Nullable Call<String> call,
#Nullable Response<String> response) {
if (response != null) {
if (response.isSuccessful()) {
MainActivity.ComObj.ShowToast(activity_new_ticket.this, response.body() + "", Toast.LENGTH_SHORT);
ResetWidjet();
pd.cancel();
} else {
try {
assert response.errorBody() != null;
MainActivity.ComObj.ShowToast(activity_new_ticket.this, response.errorBody().string(), Toast.LENGTH_LONG);
} catch (IOException e) {
e.printStackTrace();
}
pd.cancel();
}
}
}
#Override
public void onFailure(#Nullable Call<String> call,#Nullable Throwable t) {
if (t != null) {
MainActivity.ComObj.ShowToast(activity_new_ticket.this, t.getMessage(), Toast.LENGTH_SHORT);
}
pd.cancel();
}
});
}
Hope this will help you
i am able to upload image using postman :
but when i tried using multi-part entity using retrofit i am not able to upload that it tell file is not find in server below is my code:
public void visitrecord_existingtask(int userId, String companyId, String taskId, String actionTaken, String timeSpend, double lat, double longi, ArrayList<String> filePaths) {
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("userid", String.valueOf(userId));
builder.addFormDataPart("companyid", companyId);
builder.addFormDataPart("taskid", taskId);
builder.addFormDataPart("task_actiontaken", actionTaken);
builder.addFormDataPart("timespent", timeSpend);
builder.addFormDataPart("latitude", String.valueOf(lat));
builder.addFormDataPart("longitude", String.valueOf(longi));
for (int i = 0; i < filePaths.size(); i++) {
File file = new File(filePaths.get(i));
builder.addFormDataPart("files", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file));
}
MultipartBody requestBody = builder.build();
Call<VisitrecordExistingtask> call = webAPIInterface.visitrecordExistingtask(requestBody);
call.enqueue(new Callback<VisitrecordExistingtask>() {
#Override
public void onResponse(Call<VisitrecordExistingtask> call, Response<VisitrecordExistingtask> response) {
visitrecordlistner.showLoginResult(response.code(), response.body());
}
#Override
public void onFailure(Call<VisitrecordExistingtask> call, Throwable t) {
visitrecordlistner.showError(t);
}
});
}
this is my code which i am using file upload to server i have to send soem parameter plus image file to server but its not able to find image in server can any one please suggest me what i am doing wrong .
I have a node.js script which should handle file uploads, also multiple at once. Uploading pictures and voices work just fine. However, video files at around 10 MB or larger do not upload. Sometimes it doesn't work at all and sometimes it gets stuck in the fs.writeFile function. Maybe there is a better way general as I came up with many parts in the code on my own. I need the md5 hash before creating the file on disk because its path will be generated from the hash. Also I get a SocketTimeoutException on the Android side. Code is mainly focused on that part right now, so don't worry about the missing input validation and onProgress.
NodeJS:
server.route({
method: 'POST',
path: '/uploadFile',
config: {
payload: {
output: 'stream',
allow: 'multipart/form-data',
maxBytes: 100*1024*1024 //100 mb
}
}, handler: async function (request, reply)
{
await incoming_uploadFile(request, reply);
}
});
...........
var joi = require('joi');
import { Paths } from "../util/Paths";
import * as fs from 'fs';
let data;
let numOfFiles: number;
export async function incoming_uploadFile(request, reply) {
data = request.payload;
await Application.InitializeSocket(null, "UploadFile");
let userID = await Application.AuthUser(JSON.parse(data['auth']));
numOfFiles = parseInt(data['numOfFiles']);
if (numOfFiles > 0)
upload(0);
}
async function upload(i: number)
{
const file = data['file' + i];
const meta = data['fileMeta' + i];
const metaJson = Application.StringToJson(meta);
const fileType: string = metaJson['fileType'];
const extension: string = metaJson['extension'];
var crypto = require('crypto');
const md5 = crypto.createHash('md5');
var length = parseInt(file.hapi.headers["content-length"]);
let buffer: Buffer = new Buffer(length);
let bufPos : number = 0;
file.on('data', function (b : Uint8Array) {
for (var i = 0; i < b.byteLength; ++i)
buffer.writeUInt8(b[i], bufPos++);
});
file.on('end', function (err) {
var hash = md5.update(buffer.toString("base64")).digest("hex");
const filePath: string = Paths.getFilePath(hash, fileType, extension);
// Creates all dirs that are missing on the path
var shell = require('shelljs');
shell.mkdir('-p', require('path').dirname(filePath));
console.log("writing buffer to file...");
fs.writeFile(filePath, buffer,null);
if ((++i) < numOfFiles)
upload(i);
});
}
Android uploading the file(s):
public static void uploadAttachments(ArrayList<EventAttachment> attachments)
{
OkHttpClient client = new OkHttpClient();
// Add attachments
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("numOfFiles",String.valueOf(attachments.size()));
for (int i = 0; i < attachments.size();++i) {
EventAttachment attachment = attachments.get(i);
File file = new File(attachment.getPath());
String extension = MimeTypeMap.getFileExtensionFromUrl(attachment.getPath());
String type = null;
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
} else {
Log.e("x", "Could not get extensions of file " + file.getAbsolutePath() + ". File upload aborted.");
return;
}
ProgressRequestBody p = new ProgressRequestBody(RequestBody.create(MediaType.parse(type), file), new ProgressRequestBody.Listener() {
#Override
public void onProgress(int progress) {
}
});
builder.addFormDataPart("file" + i, file.getName(), p);
HashMap<String, String> hm = new HashMap<>();
hm.put("extension", extension.replace(".", ""));
hm.put("fileType", String.valueOf(attachment.getType()));
builder.addFormDataPart("fileMeta" + i, new JSONObject(hm).toString());
}
JSONObject jObj = new JSONObject();
builder.addFormDataPart("auth", putDefaultHeader(jObj).toString());
MultipartBody mb = builder.build();
okhttp3.Request request = new Request.Builder().url(EndPoint+UPLOAD_FILE).post(mb).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.e("x", "Error uploading file");
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
Thanks for your help.
Added
timeout: false,
parse: true
on the config payload and works for now.
I want to send a photo from local android gallery to the server http Tomcat. For the communication I'm using retrofit. I've established the connection between device and server, and the programme get into servers function but all objects in params are null.
That's the device function declaration on the client side:
#Multipart
#POST("/monument/photo/upload")
void addMonumentPhoto(#Part("MonumentID") Integer monumentId,
#Part("name") String name,
#Part("subscript") String subscript,
#Part("photo") TypedFile photo,
Callback<Photo> callback);
... and that's how I call it:
photo = _resizePhoto(new File(monument.getUriZdjecie()));
typedFile = new TypedFile("multipart/mixed", photo);
//long bytes = photo.length();
if (photo.exists()) {
MonumentsUtil.getApi().addMonumentPhoto(monument.getIdZabytek(),
"podpis",
"Main photo",
typedFile,
new Callback<Photo>() {
#Override
public void success(Photo aPhoto, Response response) {
monument.setUriZdjecie(aPhoto.getUri());
MonumentsUtil.getApi().addMonument(monument.getNazwa(),
monument.getOpis(),
monument.getDataPowstania(),
monument.getWojewodztwo(),
monument.getUriZdjecie(),
monument.getMiejscowosc(),
monument.getKodPocztowy(),
monument.getUlica(),
monument.getNrDomu(),
monument.getNrLokalu(),
monument.getKategoria(),
monument.getLatitude(),
monument.getLongitude(),
new MonumentsCallback());
}
#Override
public void failure(RetrofitError retrofitError) {
Log.e(TAG, retrofitError.getMessage());
}
});
}
and the server's method:
#RequestMapping(value = "/monument/photo/upload")
public
#ResponseBody
Photo requestMonumentPhotoAdd(#RequestParam(value = "MonumentID", required = false) Integer monumentId,
#RequestParam(value = "name", required = false) String name,
#RequestParam(value = "subscript", required = false) String subscript,
#RequestParam(value = "photo", required = false) MultipartFile file,
HttpServletRequest request) {
Photo photo = new Photo();
if (monumentId != null)
photo.setIdZabytek(monumentId);
photo.setUri(URL + "/images/" + name);
photo.setPodpis(subscript);
photo = monumentsRepo.addPhoto(photo);
String filePath = "D:\\Projects\\Images\\" + monumentId + "_" + photo.getIdZjecia();
if (file != null) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(filePath)));
stream.write(bytes);
stream.close();
photo.setUri(filePath);
monumentsRepo.updatePhoto(photo);
return photo;
} catch (Exception e) {
return null;
}
} else {
return null;
}
}
else {
return null;
}
}
Can anybody help me and explain why all objects after geting into the servers method are null?
Maybe method is wrogly writen or the mime field of TypedFile is wrogly chosen but I read that the "multipart/mixed" mime type is for messages with various types of object included in message. I don't have any idea so any advice will be helpful.
Try when creating your TypedFile object to use "image/*" as your mime type. For that "part" it is of that specific type. The "mixed" is likely for the submit as a whole, not the single part that is the file.
typedFile = new TypedFile("image/*", photo);
I also had the similar problems and after few hours trying I finally built image uploading functionality to remote server.
To upload image you need to create the API properly and also need to pass the image properly.
This should work fine for you:
In Retrofit client you need to set up the image as followed:
String photoName = "20150219_222813.jpg";
File photo = new File(photoName );
TypedFile typedImage = new TypedFile("application/octet-stream", photo);
RetrofitClient.uploadImage(typedImage, new retrofit.Callback<Photo>() {
#Override
public void success(Photo photo, Response response) {
Log.d("SUCCESS ", "SUCCESS RETURN " + response);
}
#Override
public void failure(RetrofitError error) {
}
});
API SET UP:
#Multipart
#POST("/")
void uploadImage(#Part("file") TypedFile file, Callback<Photo> callback);
Remote Server Side PHP Code to handle the image:
........
$pic = 'uploaded_images/' . $imagename . '.jpg';
if (!move_uploaded_file($_FILES['file']['tmp_name'], $pic)) {
echo "posted";
}
.........
If it helps any one please recognize me..thanks a lot..