facebook sdk: share local picture with text is driving me crazy - android

GOAL
In my camera app i want to let user share a picture with pre-formatted text and a description on the user's facebook wall.
INTRO
I Googled a lot and followed "the terrific" facebook-getting-started, trying many things, for !!days!!... no completely working solutions found yet.
At least i think i got some points:
The great Android Intent action_send works great but not choosing facebook, that works for text OR for pictures, not for both (!!), see here
applicationID, hashxxx, and everything else needed to link android app to facebook login, all things that i really don't understand and don't want to, done and at last working (thanx facebook for all this sh*t!!)
share with facebook can be done (see here):
3a. using the facebook app (installed in the device)
3b. using a login session (if facebook app is not installed)
Facebook wants us to use its SDK, it's very [b|s]ad, but i can stand it.
case 3a - facebook suggests us to use the shareDialog, and -fighting a lot with code snippets and samples suggested!- i have been able to do it, but i need it to work also if facebook app is not installed (case 3b.)
case 3b - facebook suggests to use the "ugly" feedDialog as a fallback (see here).
6a. feedDialog needs login and it's ok...
6b. it seems feedDialog cannot share local images, i really don't understand why... here facebook guide talks only about "URL" for the "picture" keyword...
5c. then i think i must use Request, i tried implementing it but nothing happened, i think i'm missing something... No useful references (=working examples) found.
CODE SNIPPETS copy/paste/edit from SO and developers.facebook
ShareDialog and session management in case facebook app is not installed IT'S WORKING
/**
* share image with facebook, using facebook sdk
* #param pathToImage
*/
private void shareWithFacebook(String pathToImage) {
Log.i("SHARE", "share with facebook");
if (FacebookDialog.canPresentShareDialog(getApplicationContext(), FacebookDialog.ShareDialogFeature.SHARE_DIALOG)) {
// Publish the post using the Share Dialog
Log.i("SHARE", "share with ShareDialog");
FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(this)
.setCaption("Sharing photo taken with MyApp.")
.setName("Snail Camera Photo")
.setPicture("file://"+pathToImage)
.setLink("http://myapplink")
.setDescription("Image taken with MyApp for Android")
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else {
// maybe no facebook app installed, trying an alternative
// here i think i need a session
if (Session.getActiveSession() != null && Session.getActiveSession().isOpened()) {
publishFeedDialog(pathToImage);
} else {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
List<String> permissions = new ArrayList<String>();
permissions.add("publish_actions");
session.openForRead(new Session.OpenRequest(this)
.setPermissions(permissions)
.setCallback(mFacebookCallback));
} else {
Session.openActiveSession(this, true, mFacebookCallback);
}
}
}
}
private Session.StatusCallback mFacebookCallback = new Session.StatusCallback() {
public void call(final Session session, final SessionState state, final Exception exception) {
if (state.isOpened()) {
String facebookToken = session.getAccessToken();
Log.i("SHARE", facebookToken);
Request.newMeRequest(session, new Request.GraphUserCallback() {
public void onCompleted(GraphUser user, com.facebook.Response response) {
publishFeedDialog(MP.LAST_TAKEN_FOR_GALLERY);
}
}).executeAsync();
}
}
};
feedDialog snippet, works for text fields, links, and remote url, but DOESN'T WORK FOR LOCAL PICTURES using "file://..." nor "file:///...". Error message: picture URL is not properly formatted.
private void publishFeedDialog(String pathToImage) {
Bundle params = new Bundle();
params.putString("name", "myapp Photo");
params.putString("caption", "Sharing photo taken with myapp.");
params.putString("description", "Image taken with myapp for Android");
params.putString("link", "http://myapp.at.playstore");
params.putString("picture", "file://"+pathToImage);
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(EnhancedCameraPreviewActivity.this,//getApplicationContext(),
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
public void onComplete(Bundle values,
FacebookException error) {
Log.i("SHARE", "feedDialog.onComplete");
if (error == null) {
// story is posted
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(getApplicationContext(),
"Posted story, id: "+postId,
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(getApplicationContext(),
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
})
.build();
feedDialog.show();
}
Another try, using Request, it says:
photo upload problem. Error={HttpStatus: 403, errorCode: 200,
errorType: OAuthException, errorMessage: (#200) Requires extended
permission: publish_actions}
I tried adding publish_actions permission in the session management above, maybe i miss something...
private void publishFeedDialog(String pathToImage) {
Request request=Request.newPostOpenGraphObjectRequest(
Session.getActiveSession(),
"PhotoUpload",
"myApp Photo Upload",
"file://"+pathToImage,
"http://myapp.at.playstore",
"Image taken with myApp for Android",
null,
uploadPhotoRequestCallback);
request.executeAsync();
}
Last try with Request, absolutely nothing happens, both with or without "picture" keyword.
private void publishFeedDialog(String pathToImage) {
Bundle parameters = new Bundle();
parameters.putString("message", "Image taken with myApp for Android");
parameters.putString("picture", "file://"+pathToImage);
parameters.putString("caption", "myApp Photo");
Request request = new Request(Session.getActiveSession(), "/me/feed", parameters, null);
// also tried: Request request = new Request(Session.getActiveSession(), "/me/feed", parameters, com.facebook.HttpMethod.POST);
request.executeAsync();
}
QUESTIONS
-1- Are there some faults in my 1..6 points?
-2- Can i share a local picture using FeedDialog?
-3- if not, how to when facebook app is not installed?
Thanks a lot!

I have the same problem, but I have a workaround.
I can't find any wrong reasoning in your point 1-6, look like the same issues I've come acrossed.
You can't share pictures locally, but...
Code snippet below:
This will upload the picture to the users profile and post it on his\hers wall, afterwhich you can get the URL if needed:
private void uploadPicture(final String message, Session session) {
Request.Callback uploadPhotoRequestCallback = new Request.Callback() {
#Override
public void onCompleted(com.facebook.Response response) {
if (response.getError() != null) {
Toast.makeText(getActivity(), "Failed posting on the Wall", Toast.LENGTH_LONG).show();
return;
}
Object graphResponse = response.getGraphObject().getProperty("id");
if (graphResponse == null || !(graphResponse instanceof String) ||
TextUtils.isEmpty((String) graphResponse)) {
Toast.makeText(getActivity(), "Failed uploading the photo\no respons", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), "Succsefully posted on the facebook Wall", Toast.LENGTH_LONG).show();
}
}
};
// Execute the request with the image and appropriate message
Request request = Request.newUploadPhotoRequest(session, profileBitmap, uploadPhotoRequestCallback);
Bundle params = request.getParameters();
params.putString("message", message);
request.executeAsync();
}
And to start facebook login when you don't have the APP, it's simpler, I use the following code snippet for calling the facebook SDK on facebook button:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.faceBookButton:
if (((imagePath != null && !imagePath.equals("")) || (message != null && !message.equals("")))) {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForPublish(new Session.OpenRequest(this)
.setPermissions(Arrays.asList("public_profile", "publish_actions"))
.setCallback(statusCallback));
} else {
if (profileBitmap != null) {
uploadPicture(message, session);
} else {
publishFeedDialog(message);
}
}
} else {
Toast.makeText(getActivity(), getString(R.string.checkin_fail), Toast.LENGTH_SHORT).show();
}
break;
}
}
In my case publishFeedDialog accepts the message you want to pass on, and not the image, but it doesn't matter. It opens up Facebook's message dialog anyway to which I haven't yet found a way to pass a predefined message from my EditText widget.

Related

Facebook SDK - Wrong ID while invating friends

I want to send invites to user's facebook friends. For that I use the following code:
String KEY_MESSAGE = "message";
Bundle params = new Bundle();
params.putString(KEY_MESSAGE, "Learn how to make your Android apps social");
WebDialog requestsDialog = (new WebDialog.RequestsDialogBuilder(context, Session.getActiveSession(), params))
.setOnCompleteListener(new WebDialog.OnCompleteListener() {
#Override
public void onComplete(Bundle values, FacebookException error) {
if (error == null) {
Log.w(TAG, "Posted successfully. Values: " + values);
Toast.makeText(context, "Success", Toast.LENGTH_SHORT).show();
} else if (error instanceof FacebookOperationCanceledException) {
Log.e(TAG, "Post canceled");
} else {
Log.e(TAG, "Strange error: " + error);
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
}
}
})
.build();
requestsDialog.show();
My app shows request dialog. I select one friend and push "Send" button. Then I find out this friend id via this website. My logs:
Posted successfully. Values: Bundle[{to[0]=<unknown-friend-id>, request=388113714696190}]
Friend that I want to bу invited do not recive any invites. And his id do not equals "unknown-friend-id". Why can it be wrong? I've got no ideas
P.S. "unknow-friend-id" is set of numbers. It is someones id. I decided not to publish it. And don't look throw the comments. They are for priveous version of the question.
Thanks #WizKid. As he said:
It doesn't work because your app hasn't a canvas version. For more information you should read this

Unable to post an image from drawable to facebook

I am trying to pass an image from the drawables folder to the feed dialogue. But I am unable to view the image in facebook feed dialogue. Rest of the parameters are available. I am using facebook SDK 3.5. Here is the function for showing feed dialog.
private void publishFeedDialog() {
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.ic_launcher);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitMapData = stream.toByteArray();
Bundle params = new Bundle();
params.putByteArray("picture", bitMapData);
params.putString("name", "Facebook SDK for Android");
params.putString("caption", "Build great social apps and get more installs.");
params.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
params.putString("link", "https://developers.facebook.com/android");
//params.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(getActivity(),
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(getActivity(),
"Posted story, id: "+postId,
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(getActivity().getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(getActivity().getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(getActivity().getApplicationContext(),
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
})
.build();
feedDialog.show();
}
Publish feed will work only with url to image.
See picture property under feed documentation: https://developers.facebook.com/docs/reference/dialogs/feed/
If you want to publish image from your memory (like drawable folder) then you need to use: Request.newUploadPhotoRequest()
Beside this, you can use this simple open source library that supports SDK 3.5 for doing actions like publish photo, feed and so on in a very simple way: https://github.com/sromku/android-simple-facebook
UPDATE
Option 1
You can use Request.newUploadPhotoRequest(), but this method doesn't allow you to add any additional property except the image itself.
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.ic_launcher);
Request.newUploadPhotoRequest(Session.getActiveSession(), bitmap , new Request.Callback()
{
#Override
public void onCompleted(Response response)
{
// ... handle the response...
}
});
Option 2
If you want to add additional properties to the image like description, then do almost the same but with raw graph api call. The facebook implementation of Request.newUploadPhotoRequest() does exactly the same but without setting additional properties.
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.ic_launcher);
Bundle params = new Bundle();
params.putParcelable("picture", bitmap);
params.putString("message", "This is the description of the image");
params.putString("place", "1235456498726"); // place id of the image
Request request = new Request(session, "me/photos", bundle, HttpMethod.POST, new Request.Callback()
{
#Override
public void onCompleted(Response response)
{
// ... handle the response...
}
});
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();

Posting an audio MP3 file through Feed Dialog using Facebook Android SDK

I have an Android app and I have implemented sharing through Facebook SDK for Android, I am using Feed Dialog
Everything working as written, however, as the content is Audio, I now also want to share MP3 files, just like SoundCloud does. Feed Dialog accepts a "source" parameter, which seems to accept a SWF or MP3 source URL. Feed Dialog feature documentation is here.
However, when I embed Source parameter, it do exactly as it says on tin "If both source and picture are specified, only source is used." However, it don't live up to first promise which is: "The URL of a media file (either SWF or MP3) attached to this post."
My code is below:
private void publishFeedDialog() {
Bundle params = new Bundle();
params.putString("app_id", "xxxxxxxxxxxxxxx");
params.putString("name", "Name of Audio File");
params.putString("caption", "Listen to Audios");
params.putString("description", "Listen Listen Listen");
params.putString("link", "applink on store");
params.putString("picture", "picturehostedsomewhere.png");
params.putString("source", "http://www.looptvandfilm.com/blog/Radiohead%20-%20In%20Rainbows/01%20-%20Radiohead%20-%2015%20Step.MP3");
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(this,
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(getApplicationContext(),
"Shared on Facebook",
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(getApplicationContext(),
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
})
.build();
feedDialog.show();
}
What I see when I share the story is a story without any picture, it's just plain text with link, name, caption and description, no source, no picture, I assume either facebooksdk is having a problem in fetching the source or I am missing something here.
I am just wondering where I am heading wrong? Any help please?

Android Facebook SDK 3 posting to friends feed doesnt work

Can someone send REALLY working NOW simple?
I'm use next:
1) Make authorization in app
2) then on button pressed publishFeedDialog();
private void publishFeedDialog() {
Bundle params = new Bundle();
params.putString("name", "Facebook SDK for Android");
params.putString("caption", "Build great social apps and get more installs.");
params.putString("description", "The Facebook SDK for And0roid makes it easier and faster to develop Facebook integrated Android apps.");
params.putString("link", "https://developers.facebook.com/android");
params.putString("picture", "");
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(activity,
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
Log.e("TAG",values.toString());
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(activity,
"Posted story, id: "+postId,
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(activity.getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(activity.getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(activity.getApplicationContext(),
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
})
.setFrom("")
.setTo(userId)
.build();
feedDialog.show();
}
While I send messsage I see that my friend currectly recognized from Id.
I receive something like:
Webview loading URL: https://m.facebook.com/dialog/feed
Redirect URL: fbconnect://success?post_id=1266196038_167455066740536
But message in frends feed doesnt appear.
Code without .setTo(userId) send me at feed my message as normal.
In authorization I use
List<String> permission = new ArrayList<String>();
permission.add("publish_actions");
permission.add("publish_stream");
and write app_id in manifest.
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/app_id" />
Help me please!
P.S. Does send to friend's feed at facebook working now (after feb 2013) ?
(Edit): This is only applicable via the graph API.
Look here at the second last point under February 2013 Breaking Changes Now Live. Its no longer available.

OAuthException when trying to Post to Friends Wall

Im having alot of trouble trying to post to a friends wall using the Facebook api in Android. This is what I have at the moment:
if (facebook.isSessionValid()) {
String response = facebook.request((userID == null) ? "me" : userID);
Bundle params = new Bundle();
params.putString("message", "put message here");
params.putString("link", "http://mylink.com");
params.putString("caption", "{*actor*} just posted this!");
params.putString("description", "description of my link. Click the link to find out more.");
params.putString("name", "Name of this link!");
params.putString("picture", "http://mysite.com/picture.jpg");
response = facebook.request(((userID == null) ? "me" : userID) + "/feed", params, "POST");
Log.d("Tests",response);
if (response == null || response.equals("") ||
response.equals("false")) {
Log.v("Error", "Blank response");
}
} else {
// no logged in, so relogin
Log.d("1234567890", "sessionNOTValid, relogin");
}
}catch(Exception e){
e.printStackTrace();
}
But this returns with this error:
12-11 21:34:06.604: D/FACEBOOK RESPONSE(14954): {"error":{"message":"(#200) Feed story publishing to other users is disabled for this application","type":"OAuthException","code":200}}
You probably created this Facebook application recently, which means the February 2013 breaking changes are enabled.
February's Breaking Changes include:
Removing ability to post to friends walls via Graph API
We will remove the ability to post to a user's friends' walls via the Graph API. Specifically, posts against [user_id]/feed where [user_id] is different from the session user, or stream.publish calls where the target_id user is different from the session user, will fail. If you want to allow people to post to their friends' timelines, invoke the feed dialog. Stories that include friends via user mentions tagging or action tagging will show up on the friend’s timeline (assuming the friend approves the tag). For more info, see this blog post.
We are disabling this feature starting in February, if you wish to enable it (only temporarily until February), go to your app dashboard > Settings > Advanced > Disable "February 2013 Breaking Changes"
I highly recommend against doing so, however, since starting February this functionality will cause your app to throw the same error again.
I have the solution that might help you, I am using this for my code and its working fine..
private void publishFeedDialog(String friend_uid) {
try{
Session mCurrentSession = Session.getActiveSession();
SessionTracker mSessionTracker = new SessionTracker(
getBaseContext(), new StatusCallback() {
public void call(Session session, SessionState state,
Exception exception) {
}
}, null, false);
String applicationId = Utility
.getMetadataApplicationId(getBaseContext());
mCurrentSession = mSessionTracker.getSession();
if (mCurrentSession == null
|| mCurrentSession.getState().isClosed()) {
mSessionTracker.setSession(null);
Session session = new Session.Builder(getBaseContext())
.setApplicationId(applicationId).build();
Session.setActiveSession(session);
mCurrentSession = session;
}
if (!mCurrentSession.isOpened()) {
Session.OpenRequest openRequest = null;
openRequest = new Session.OpenRequest(
NewFriendList.this);
if (openRequest != null) {
openRequest
.setDefaultAudience(SessionDefaultAudience.FRIENDS);
openRequest.setPermissions(Arrays.asList("email", "publish_actions"));
openRequest
.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
mCurrentSession.openForPublish(openRequest);
}
}
if (regobj != null && friend_uid != null ) {
final Activity activity = this;
Bundle params = new Bundle();
//This is what you need to post to a friend's wall
params.putString("from", "" + regobj.MyFBID);
params.putString("to", friend_uid);
//up to this
params.putString("name", "Facebook SDK for Android");
params.putString("caption", "Build great social apps and get more installs.");
params.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
params.putString("link", "https://developers.facebook.com/android");
params.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
WebDialog feedDialog = (new WebDialog.FeedDialogBuilder(this, mCurrentSession, params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values, FacebookException error) {
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(activity,
"Posted story, id: "+postId,
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(activity,
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(activity,
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(activity,
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
}).build();
feedDialog.show();
}
}catch(Exception e)
{
Log.d("Error", ""+e.toString());
}
}
This code will work for only one user, if you want to send it to multiple user then you can use RequestsDialogBuilder instead of WebDialog.

Categories

Resources