I try many solutions but no once work for me.
I'm receiving images data in this way:
ArrayList<String> filePaths = data.getStringArrayListExtra(Pix.IMAGE_RESULTS);
and uploading images using multipart
MultipartBody requestBody = builder.build();
Call<Status_Response> call = taskMetServer.uploadMultiplePics(requestBody.parts());
call.enqueue(new Callback<Status_Response>() {
#Override
public void onResponse(Call<Status_Response> call, Response<Status_Response> response) {
if(response.isSuccessful()){
Status_Response status_response = response.body();
assert status_response != null;
String msg = status_response.getStatus();
Log.d("myMessage", "\n\nStatus: "+msg);
progressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), "Success " + response.message()+response.code(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<Status_Response> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
my interface is:
#POST("test/store")
Call<Status_Response> uploadMultiplePics(
#Body List<MultipartBody.Part> images
);
but still receiving null in response instead of true of false:
2021-03-20 17:36:38.076 10582-10582/com.example.ourproductapp D/myMessage: [/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20210320-WA0082.jpeg]
2021-03-20 17:36:38.732 10582-10582/com.example.ourproductapp D/myMessage: Status: null
Thanks in advance
check your backend service, your server is getting file or not.
or you can use https://github.com/gotev/android-upload-service library
Related
I want to call SharePoint rest API form android. for this, i'm using cookies to call rest API using web view, but while calling am getting "BasicNetwork.performRequest: Unexpected response code 403".
if l call to SharePoint rest api using volley here what i tried up to.
update:i'm using this site for refrence SharePoint rest api from android
**Update:during research i found one example to connect with share point online using soap as well, any idea how to do that? **
private void sendAndRequestResponse() {
//RequestQueue initialized
Log.d(TAG, "Starting volley request to graph");
/* Make sure we have a token to send to graph */
RequestQueue queue = Volley.newRequestQueue(this);
JSONObject parameters = new JSONObject();
try {
parameters.put("key", "value");
} catch (Exception e) {
Log.d(TAG, "Failed to put parameters: " + e.toString());
}
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url,
parameters,new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
/* Successfully called graph, process data and send to UI */
Log.d(TAG, "Response: " + response.toString());
Toast.makeText(MainActivity.this, ""+response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error: " + error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Cookie","rtFa=" + RTFA + "; FedAuth=" + FedAuth);
headers.put("Accept","application/json;odata=verbose");
headers.put("Content-type","application/json;odata=verbose");
return headers;
}
};
Log.d(TAG, "Adding HTTP GET to Queue, Request: " + request.toString());
request.setRetryPolicy(new DefaultRetryPolicy(
3000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
}
I used rtfa and fed cookies to pass as header.
Update: i used share point login URL for windows auth. for and after success i store rfta and fed auth. cookies to pass token as header but i'm getting same error.
This page says that we can register a Listener to a volley request for handling errors:
https://developer.android.com/training/volley/simple
But it doesn't mention what kind of errors trigger this listener. Volley javadoc doesn't say anything about it either.
Specifically, will this listener be executed if a network error occurs.
I'm asking this because I've encountered an android code of the following form:
private void method() {
String URL = "";
final int[] status_code = new int[1];
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (status_code[0] == 200) {
// do something
} else {
// display toast
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// display toast
}
}) {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
status_code[0] = response.statusCode;
return super.parseNetworkResponse(response);
}
};
// add request to queue
}
This code seems to suggest that the registered ErrorListener isn't called for network errors.
What are the conditions which cause the ErrorListener registered to a Volley request to be called
The ErrorListener is triggered for 4xx responses and 5xx responses I cannot tell what happens though for the 3xx redirection responses as it didn't happended to me.
Here is a list with all HTTP Response codes:
https://www.restapitutorial.com/httpstatuscodes.html
I'm not exactly privy to your entire code but poking through the Volley source code:
Response.java takes in VolleyError object
VolleyError references NetworkResponses in its use.
Inspecting NetworkResponses deals with mainly HTTP status codes.
Also I'd note that VolleyError extends Exception.
So I would say the call back method is triggered when an Exception is thrown and VolleyError deals with HTTP status codes.
I just call this statement
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError) {
Log.i(TAG, "onErrorResponse: " + context.getString(R.string.error_network_timeout));
} else if (error instanceof ServerError) {
Log.i(TAG, "onErrorResponse: " + context.getString(R.string.error_server));
} else if (error instanceof NetworkError) {
//toast or log your error
} else if (error instanceof ParseError) {
Log.i(TAG, "onErrorResponse: " + context.getString(R.string.parse_error));
} else {
Log.i(TAG, "onErrorResponse: Something went wrong ");
}
You don't need to find error code
I want to send some data with retrofit including an image and three strings,
how should my WCF server side method signature be to handle these posted data if someone could help me?
The below code is my client side with retrofit(although im not sure it is well written).
#Multipart
#POST("PostBanderolDataJSON")
Call<MyResponse> PostData(#Part("banderolNr") RequestBody banderolNr, #Part("pharmacy") RequestBody pharmacy, #Part("place") RequestBody place, #Part("report_pic\"; filename=\"rp.png\" ") RequestBody file);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RetrofitApiInterface.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApiInterface api = retrofit.create(RetrofitApiInterface.class);
RequestBody reportImage = RequestBody.create(MediaType.parse("image/jpeg"), ImagePath);
RequestBody banderoNr = RequestBody.create(MediaType.parse("text/plain"), etBanderolNr.getText().toString());
RequestBody pharmacy = RequestBody.create(MediaType.parse("text/plain"), Pharmacy.getText().toString());
RequestBody place = RequestBody.create(MediaType.parse("text/plain"), Place.getText().toString());
Call<MyResponse> call = api.PostData(banderoNr,pharmacy,place,reportImage);
call.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response.isSuccessful()) {
if (!response.body().error) {
Toast.makeText(getApplicationContext(), "Data Sent Successfully...", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Some error occurred...", Toast.LENGTH_LONG).show();
}
progress.dismiss();
}
else{
Toast.makeText(getApplicationContext(),"Something went wrong with the request to the server !",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
progress.dismiss();
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
I'm working on an android app for a Facebook group. Using the graph API, I can easily post a text status but when I upload a photo, it returns error saying
(#100) The picture is not properly formatted
If I use the same code to post to my wall, the photo upload works fine.
Is this an API restriction or there is a separate approach to upload a photo to a group?
Following is my code:
Request photoRequest = Request.newUploadStagingResourceWithImageRequest(session, bitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (mProgress != null && mProgress.isShowing())
mProgress.dismiss();
if (response.getError() == null) {
Toast.makeText(NewPostActivity.this, "Successfully shared on the group", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(NewPostActivity.this, "Facebook sharing error: " + response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Bundle params = photoRequest.getParameters();
if(message != null) {
params.putString("message", message);
}
if(imageBytes != null) {
params.putByteArray("picture", imageBytes);
}
photoRequest.setParameters(params);
photoRequest.setHttpMethod(HttpMethod.POST);
photoRequest.setGraphPath(Constants.URL_FEEDS);
photoRequest.executeAsync();
EDIT
I'm using Graph API v2.3
It does seem to be possible to post a photo in a group.
You can make a POST request to photos edge from the following paths:
/{group_id}/photos
When posting to this edge, a Photo will be created.
Link
Return type
Struct {
id: numeric string,
post_id: token with structure: Post ID,
}
It seems like the POST request to /<group-id>/feed doesn't allow to upload a photo (which otherwise works for /me/feed). I finally got this working with the /<group-id>/photos edge as suggested. Following is my code - hoping that it helps some:
Request photoRequest = Request.newUploadStagingResourceWithImageRequest(session, bitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (mProgress != null && mProgress.isShowing())
mProgress.dismiss();
if (response.getError() == null) {
Toast.makeText(NewPostActivity.this, "Successfully shared on the group", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(NewPostActivity.this, "Facebook sharing error: " + response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Bundle params = photoRequest.getParameters();
if(message != null) {
params.putString("message", message);
photoRequest.setGraphPath(Constants.URL_FEEDS);
}
if(imageBytes != null) {
params.putByteArray("picture", imageBytes);
photoRequest.setGraphPath(Constants.URL_PHOTOS);
}
photoRequest.setParameters(params);
photoRequest.setHttpMethod(HttpMethod.POST);
photoRequest.executeAsync();
I am trying to send image files from my android app to a back end server. On Postman, images are sent and response code:200 is received.
However, trying to send images from my android app using retrofit, I keep receiving response code:500 Internal Server Error. Here is my code:
public interface RetrofitInterface {
#Multipart
#POST("uploads/addImage")
Call<ResponseBody> uploadImage(#Part MultipartBody.Part image);
}
The NetworkClient
public class NetworkClient {
private static Retrofit retrofit;
public static Retrofit getRetrofit(){
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS).build();
if(retrofit == null){
String BASE_URL = "https://addimage.herokuapp.com/";
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
addConverterFactory(GsonConverterFactory.create()).client(okHttpClient).build();
}
return retrofit;
}
}
And then the call
private void uploadImage(Uri imageUri){
File file = new File(imageUri.toString());
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);
Retrofit retrofit = NetworkClient.getRetrofit();
RetrofitInterface retrofitInterface = retrofit.create(RetrofitInterface.class);
Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("UploadImage", "Yeepee!!! = "+response.message());
}else Log.d("UploadImage", "Response failure = "+response.message());
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
// "Connection Timeout";
Log.e("UploadImage", "Connection Timeout");
} else if (t instanceof IOException) {
// "Timeout";
Log.e("UploadImage", "Timeout");
} else {
//Call was cancelled by user
if(call.isCanceled()) {
Log.e("UploadImage", "Call was cancelled forcefully");
} else {
//Generic error handling
Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
}
}
}
});
}
I am not sure if it's a server error since images upload successfully from Postman. I am very confused and I am not sure what I am doing wrong.
According to your Postmen screen shot there is no key for image file can you try like below
remove this line
MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);
And add this one
MultipartBody.Part body = MultipartBody.Part.createFormData("", "image.jpg", requestBody);
Generally 500 Internal Server error means there is something wrong in the server, but if the Postman is giving 200 that means the server part is OK, there's something wrong in your code.
try changing this line
File file = new File(imageUri.toString());
to this
File file = new File(imageUri.path);
And also make sure that the key name you used is same as the response key name
Thank you all for your responses. I have been able to resolve and it turned out to be a conflict between my request body and what the server was expecting.
For my case, I was sending a different mime-type(a .jpg), where the server developer made the server look for .jpeg and .png.
This was how I got to see the error and resolve the conflict.
Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("UploadImage", "Yeepee!!! = "+response.message());
}else {
Log.d("UploadImage", "Response failure = "+response.message());
try {
Log.d("UploadImage", "Response failure = "+response.errorBody().string());
} catch (IOException e) {
Log.d("UploadImage", "IOException = "+e.getMessage());
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
// "Connection Timeout";
Log.e("UploadImage", "Connection Timeout");
} else if (t instanceof IOException) {
// "Timeout";
Log.e("UploadImage", "Timeout");
} else {
//Call was cancelled by user
if(call.isCanceled()) {
Log.e("UploadImage", "Call was cancelled forcefully");
} else {
//Generic error handling
Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
}
}
}
});
The response.errorBody().string() got the error message from the server and I was able to resolve the conflict.