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();
Related
My current success response is this:
{"status":"success","message":"msg here"}
with code 200
And my error response is this:
{"status":"failure","message":"There was a validation error","errors":{"shippingAddress":{"phoneNumber":"Please enter a valid phone number"}}}
with code 400
my problem is the code below is not working because it always go inside onFailure()
if (response.isSuccessful()) {
// do something
} else if (response.code() == 400) {
Gson gson = new Gson();
ErrorPhone message = null;
if (response.errorBody() != null) {
message = gson.fromJson(response.errorBody().charStream(), ErrorPhone.class);
}
if (message != null) {
Toast.makeText(context, message.getErrors().getShippingAddress().getPhoneNumber(), Toast.LENGTH_LONG).show();
} else {
String errors = "";
try {
JSONObject jObjError = new JSONObject(response.errorBody().string());
errors = jObjError.getJSONObject("errors").getJSONObject("shippingAddress").getString("phoneNumber");
} catch (JSONException | IOException e) {
e.printStackTrace();
}
if (!errors.equals("")) {
Toast.makeText(context, errors, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, response.message(), Toast.LENGTH_LONG).show();
}
}
}
and inside onFailure i cant listen to errorBody to handle the response
Use Retrofit interface called onResponse and place your code there. As Retrofit uses two different callback methods for the two possible outcomes of a network requests: either a failure or a successful request. Retrofit will call the appropriate callback method depending on the result. If the request was successful, Retrofit will also pass you the response of the server.
For more view this link:https://square.github.io/retrofit/2.x/retrofit/retrofit2/Callback.html and https://futurestud.io/tutorials/java-basics-for-retrofit-callbacks that will help you more to learn about retrofit Call-backs
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
I have an android app which uses Robospice with Google HTTP client to send RESTful request to a server.
All works fine if result is successfully returned but if an exception is returned from my service, the Robospice listener doesn't catch the exception.
public final class FBUserSaveListener implements RequestListener<HttpResponse> {
#Override
public void onRequestFailure( SpiceException spiceException ) {
if(progressDialog.isShowing())
{
progressDialog.dismiss();
}
Toast.makeText(getActivity(),
"Error: " + spiceException.getMessage(), Toast.LENGTH_SHORT)
.show();
Intent i = new Intent(getActivity(), ErrorActivity.class);
startActivity(i);
}
#Override
public void onRequestSuccess(HttpResponse response) {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
if(response.getStatusCode() == AppConstants.HTTP_CODE_CREATED_201) {
Intent intent = new Intent(getActivity(), PoolMainActivity.class);
startActivity(intent);
}
else{
//Request was sent successfully but the response was wrong
// Redirect to error page
Intent i = new Intent(getActivity(), ErrorActivity.class);
startActivity(i);
}
}
}
In the above code, when the external service returns an exception, the onRequestFailure() is not hit at all.
My request is :
public HttpResponse loadDataFromNetwork() throws Exception{
String url = context.getString(R.string.BASE_SERVICE_URL) + context.getString(R.string.USER_FB_LOGIN_SAVE);
HttpRequest request = getHttpRequestFactory()//
.buildPostRequest(new GenericUrl(url), ByteArrayContent.fromString("application/json", fbLoginBeanJson));
request.setParser(new com.google.api.client.json.jackson2.JacksonFactory().createJsonObjectParser());
return request.execute();
}
Did I miss something in the Robospice implementation of RESTful services ?
I managed to solve this by debugging my fragment's life cycle.
I realized that the spiceManager was getting cleared due to the changes in my fragment's life cycle. Saw the FAQ section in robospice and it helped me a lot.
Made the spiceManager start and end in the onAttach and onDetach methods of my fragment respectively.
In my app I am using Parse.com and Facebook login, and the Facebook login is working and I am now trying to save the email of the user who signed. I am doing this like this:
Request.newMeRequest(ParseFacebookUtils.getSession(), new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
String email = user.getProperty("email").toString();
Log.i(TAG, email);
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.put("email", email);
currentUser.saveInBackground();
}
}
}).executeAsync()
But then when I run I get java.lang.NullPointerException at this line currentUser.put("email", email); But I log email before this and it is not null and I have a email attribute in my User class on parse, so Im not sure why this?
Here the code that comes before to set up the FB Login you should need it and it is working but just in case.
public void onLoginClick(View v) {
progressDialog = ProgressDialog.show(LoginActivity.this, "", "Logging in...", true);
final List<String> permissions = Arrays.asList("public_profile", "email");
// NOTE: for extended permissions, like "user_about_me", your app must be reviewed by the Facebook team
// (https://developers.facebook.com/docs/facebook-login/permissions/)
ParseFacebookUtils.logIn(permissions, this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
progressDialog.dismiss();
if (user == null) {
Log.d(TAG, "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d(TAG, "User signed up and logged in through Facebook!");
showSelectSchoolActivity();
} else {
Log.d(TAG, "User logged in through Facebook!");
showMainActivity();
}
}
});
Thanks for the help :)
for checking the response you should always use (err==null) as the condition for success. Only after you have recieved the response from the server and err==null then you can check for current user. You should also have a check for when err!=null. Then get the error message from the err.getCode() and check what the error code is.
I had my app posting feed stories to facebook fine until yesterday.
Now it stopped working and sends this error in the callback:
"com.facebook.FacebookException: could not construct request body"
This comes from:
response.getError();
Strangely the sample app from facebook stopped working and is now reporting the same error, I'm quite sure I didn't change anything on it.
Here's the sample app function:
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption", "Build great social apps and get more installs.");
postParams.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link", "https://developers.facebook.com/android");
postParams.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
return;
}
JSONObject graphResponse = response
.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i("publishStory",
"JSON error "+ e.getMessage());
}
Toast.makeText(getApplicationContext(), postId,Toast.LENGTH_LONG).show();
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}
Can anyone help please!
Thank you in advance.
Now it works...I've turned off my computer and Eclipse during the night and now restarted
I guess it was some bug in the compiler.