14

I have added sharing functionality to Android app as described here https://developers.facebook.com/docs/android/share-dialog/#setup

But I have noticed that if user is cancelled sharing activity onComplete is called anyway

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    uiHelper.onActivityResult(requestCode, resultCode, data, new FacebookDialog.Callback() {
        @Override
        public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data) {
            Log.e("Activity", String.format("Error: %s", error.toString()));
        }

        @Override
        public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) {
            Log.e("Activity", "Success!");
        }
    });
}

I have also looked in to Bundle which is returned. Even if I cancel share dialog I get

com.facebook.platform.extra.DID_COMPLETE=true

How can I get result that user really shared data on facebook? (Without making separate login with facebook button. Maybe some permissions need to be added?)

Alex M
  • 2,756
  • 7
  • 29
  • 35

6 Answers6

7

See https://developers.facebook.com/docs/android/share-dialog/#handling-responses

You can tell if the user has cancelled by calling

String gesture = FacebookDialog.getNativeDialogCompletionGesture(data);
if (gesture != null) {
  if ("post".equals(gesture)) {
    // the user hit Post
  } else if ("cancel".equals(gesture)) {
    // the user hit cancel
  } else {
    // unknown value
  }
} else {
  // either an error occurred, or your app has never been authorized
}

where data is the result bundle. However, it will only return a non-null value IF the user has logged in via your app (i.e. you have at least basic_info permissions). If the user has never logged in or authorized your app, then the only thing you'll see is the DID_COMPLETE, and it will always be true unless an error occurred. This is by design.

Ming Li
  • 15,672
  • 3
  • 37
  • 35
  • 1
    I just tried with 3.6, and it seems to work fine for me. The Scrumptious app uses this mechanism in its callback. – Ming Li Dec 11 '13 at 14:53
  • 1
    It will work if Facebook login is integrated, otherwise (for examlple, only use facebook share dialog) getNativeDialogCompletionGesture() return null. – Wayne Dec 12 '13 at 03:11
  • Please see the docs I linked to in the answer. The completion gesture is available *ONLY* if the user has already logged in via your app (i.e. gave your app at least read permissions). This is the expected behavior. – Ming Li Dec 12 '13 at 17:05
  • I know but on previous version of Facebook Sdk, the completion gesture is available even when user not logged in. – Wayne Dec 12 '13 at 17:08
  • They don't need to be currently logged in, they just need to have authorized your app at some point in the past (and haven't removed your app yet). This behavior has not changed between releases. – Ming Li Dec 12 '13 at 19:34
  • Before updated to sdk version 3.6 I can use getNativeDialogCompletionGesture to check user action (share or cancel) even when i just use share dialog without authorization but now authorization is required. – Wayne Dec 13 '13 at 03:20
  • I'm able to post, but it always return null for me, doesn't matter if I canceled or if the post was successful... why? – JHSnows Mar 27 '14 at 17:23
  • 1
    The gesture is only available to apps who have been given permissions by the user. – Ming Li Mar 28 '14 at 19:40
  • The link at the top doesn't work anymore. This is the correct link: https://developers.facebook.com/docs/android/share#linkshare-handlingresponses – Shygar Jul 12 '14 at 17:27
5

In order to obtain the result for the sharing, your app needs to have at least the basic_info permission.

To solve that, just open an session (this will automatically request the basic_info permission):

Session.openActiveSession(this /*your activity*/, 
                          true /*allows the UI login to show up if needed*/, 
                          new Session.StatusCallback() {
    @Override
    public void call(Session session, SessionState state, Exception exception) {
        Log.i("[Facebook]", "Session: " + state.toString());
        if (session.isOpened()) {
           /// now you are good to get the sharing results
        }
    }
});

You can find more information in here: https://developers.facebook.com/docs/android/getting-started/

JHSnows
  • 431
  • 1
  • 6
  • 14
3
@Override
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) {
    if (data.getString("com.facebook.platform.extra.COMPLETION_GESTURE").equals("cancel"))
        return;
}

the value of data.getString("com.facebook.platform.extra.COMPLETION_GESTURE") is "post" when the user did post on Facebook.

Alex M
  • 2,756
  • 7
  • 29
  • 35
Rony Tesler
  • 1,207
  • 15
  • 25
3

Implement FacebookCallback<Sharer.Result> to know whether sharing was successful or cancelled or there was an error.

You can use the code below in Activity and in Fragment as well. When using in Fragment make sure you pass this in ShareDialog constructor. If you pass getActivity() then onActivityResult method will not be triggered in Fragment.

private CallbackManager callbackManager;

private void shareYourContentOnFacebook() {

    callbackManager = CallbackManager.Factory.create();
    ShareDialog shareDialog = new ShareDialog(this);
    shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
        @Override
        public void onSuccess(Sharer.Result result) {
            Log.d(this.getClass().getSimpleName(), "shared successfully");
            //add your code to handle successful sharing
        }

        @Override
        public void onCancel() {
            Log.d(this.getClass().getSimpleName(), "sharing cancelled");
            //add your code to handle cancelled sharing

        }

        @Override
        public void onError(FacebookException error) {
            Log.d(this.getClass().getSimpleName(), "sharing error");
            //add your code to handle sharing error

        }
    });

    if (ShareDialog.canShow(ShareLinkContent.class)) {

        ShareLinkContent shareLinkContent = new ShareLinkContent.Builder()
                .setContentTitle("Your content title")
                .setContentDescription("Your content description")
                .setContentUrl(Uri.parse(""http://your-content-url.com""))
                .build();

        shareDialog.show(shareLinkContent);

    }

}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    callbackManager.onActivityResult(requestCode, resultCode, data);
}
dzikovskyy
  • 5,027
  • 3
  • 32
  • 43
1

Use this code:-

/**
 * Facebook Dialog Callback 
 * 
 * Called up when come back from Share Dialog
 * 
 */
private class FacebookDialogCallBack implements FacebookDialog.Callback
{
    @Override
    public void onComplete(PendingCall pendingCall, Bundle data) 
    {
        //Show Toast Message
        showToastMessage(data);
    }

    @Override
    public void onError(PendingCall pendingCall, Exception error, Bundle data) 
    {
        //Show Toast Message
        showToastMessage(data);
    }
}
//Show Toast Message
private void showToastMessage(Bundle data)
{
    //Get Native Dialog Did Complete
    boolean didComplete = FacebookDialog.getNativeDialogDidComplete(data);

    if(didComplete)
    {
        //Get Native Dialog Completion Gesture
        String nativeDialogCompletionGesture = FacebookDialog.getNativeDialogCompletionGesture(data);

        if (nativeDialogCompletionGesture == null || FacebookDialog.COMPLETION_GESTURE_CANCEL.equals(nativeDialogCompletionGesture))
        {
            //Show Publish Cancel Toast
            UIUtil.showToast(R.string.toast_message_share_publish_cancelled);                                               
        }
        else
        {
            //Show Success Post Toast
            UIUtil.showToast(R.string.toast_message_share_success_post);
        }
    }
    else
    {
        //Show Publish Cancel Toast
        UIUtil.showToast(R.string.toast_message_share_publish_cancelled);
    }
}
Himanshu Narang
  • 131
  • 2
  • 14
  • how to use this code ? facebookdialog.callback not recognized in my AS. its red underlined. and no import sign shown – Goofy_Phie Jul 04 '17 at 04:17
1

Heading ## private static ShareDialog shareDialog;

    private static FacebookCallback<Sharer.Result> shareCallback = new FacebookCallback<Sharer.Result>() {
        @Override
        public void onCancel() {
            Log.d("HelloFacebook", "Canceled");
        }

        @Override
        public void onError(FacebookException error) {
            Log.d("HelloFacebook", String.format("Error: %s", error.toString()));
            String title = this.getActivty().getString(R.string.error);
            String alertMessage = error.getMessage();
            showResult(title, alertMessage);
        }

        @Override
        public void onSuccess(Sharer.Result result) {
            Log.d("HelloFacebook", "Success!");
            // 不为空,才分享成功
            if (result.getPostId() != null) {
                String title = this.getActivty().getString(R.string.success);
                String id = result.getPostId();
                String alertMessage = this.getActivty().getString(R.string.successfully_posted_post, id);
                showResult(title, alertMessage);
            }
        }

        private void showResult(String title, String alertMessage) {
            new AlertDialog.Builder(this.getActivty())
                    .setTitle(title)
                    .setMessage(alertMessage)
                    .setPositiveButton(R.string.ok, null)
                    .show();
        }
    };

protected void onCreate (Bundle savedInstanceState)
{
             shareDialog = new ShareDialog(this. getActivty());
             shareDialog.registerCallback( callbackManager, shareCallback);
}
Change
  • 11
  • 2