Sharing in Android

Sharing is one of the most important functions of the Facebook platform. Whenever someone shares something from your app, the shared item appears on the person's timeline and on their friends' news feeds. For people using your app, sharing helps them communicate with their friends about what's important to them and enhances their experience in your app. For you as a developer, sharing increases awareness of your app through impressions in the Facebook news feed and, when people engage with the content posted from your app, it can send people to your app or your app's Play Store page, driving traffic and app installs.
A shared item can take two general shapes:
  • Content like a link, or a status update.
  • A structured Open Graph story, for example a story about cooking a mealrunning a race orreading a book.
The image below shows what a link shared through an app (left) and an Open Graph story (right) look like:
Items can also be shared in two different ways:
  • Using the Share Dialog, a built-in dialog that has the Facebook look-and-feel, is very easy to implement, and doesn't require the user to be logged into your app using Facebook in order to share.
  • Making API calls, which allows you more control of the sharing user experience but requires that the user is logged into your app using Facebook Login in order to be able to share, and as a result needs more implementation effort.
In this document we will go through all you need to know about sharing: we will walk you through sharing the different kinds of items using each of the available methods.
For information on how to post a status update, see the 'share a link' sections (you will find information on how to modify the link code to post a status update there).
We will explain how to make the shared items link back to your app. This way, when people engage with the items posted by your app on news feed they will be directed to your app or, if they don't have your app installed, your app's Play Store page.
This document also includes a list of all the available ways to share using the Android SDK, listing their advantages and disadvantages.

Prerequisites

Before you can share to Facebook from your app, or attempt to follow any of the sharing tutorials, you will need:
  • Your environment set up
  • A Facebook app properly configured and linked to your Android app, with SSO enabled
  • The Facebook SDK added to your project
If you haven't done this and need help doing so, you can follow our getting started guide.

Sharing a link using the Share Dialog

The Share dialog lets you build great, native sharing experiences for people using your app. It works by making a one-line call to the SDK that configures the content to share, does an app switch to the Facebook for Android app, and returns to your app once people have shared.
And here's what the dialog looks like:
You can also use this method to post a status update on the user's behalf.
Share Dialog is supported by version 3.5 and higher of the Facebook for Android app.
In order to implement the share dialog, you have to go through the following steps:
See our troubleshooting section for some additional help.

Step 1: Setup

On Android, apps must use a UiLifecycleHelper to set a callback to handle the result of opening the Share Dialog. First, add a UiLifecycleHelper class level instance with:
private UiLifecycleHelper uiHelper;
Then configure the UiLifecycleHelper in onCreate with:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    uiHelper = new UiLifecycleHelper(this, callback);
    uiHelper.onCreate(savedInstanceState);
}
Next, configure a callback handler that's invoked when the share dialog closes and control returns to the calling app:
@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.i("Activity", "Success!");
        }
    });
}
Finally, configure other methods on uiHelper to handle Activity lifecycle callbacks correctly.
@Override
protected void onResume() {
    super.onResume();
    uiHelper.onResume();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    uiHelper.onSaveInstanceState(outState);
}

@Override
public void onPause() {
    super.onPause();
    uiHelper.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    uiHelper.onDestroy();
}
Now your Activity is setup to use the Share dialog.
The share dialog supports status updates, link shares and publishing Open Graph actions. Each type of sharing lets people tag friends and places and choose an audience.

Here's the code for sharing a link from your app:
FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(this)
        .setLink("https://developers.facebook.com/android")
        .build();
uiHelper.trackPendingDialogCall(shareDialog.present());
You can also add an image, a caption, a description and other attributes to your post. You can read theFacebookDialog.ShareDialogBuilder reference to find out more.
To post a status update, make the link parameter null and the dialog will appear empty for the user to write their status update in it.

Step 3: Handling responses from the share dialog

After the Share dialog completes, control returns to the app and the SDK calls onActivityResult with the results of the share. Your app can handle the response by adding a FacebookDialog.Callbackto the activity's UiHelper. See Setup for an example.
In the callback's handlers, the following parameters are available:
NameCode to readTypeNotes
Did completeFacebookDialog.getNativeDialogDidCompletebooleanAlways available.true if the dialog completed successfully; falseif the dialog completed with an error.
Completion gestureFacebookDialog.getNativeDialogCompletionGestureStringOnly available if the user logged into your app using Facebook and did complete is true. Value is either postor cancel.
Post IDFacebookDialog.getNativeDialogPostIdStringOnly available if the user is logged into your app using Facebook, has granted a publish permission (e.g.publish_actions), and the user chose to share the story. If present, this is the ID of the published story.
Read these fields using static methods on FacebookDialog:
boolean didCancel = FacebookDialog.getNativeDialogDidComplete(data);
String completionGesture = FacebookDialog.getNativeDialogCompletionGesture(data);
String postId = FacebookDialog.getNativeDialogPostId(data);
If the Share Dialog returned with an error, check the error passed to the Share Dialog handler.

Step 4: Using the Feed Dialog as fallback

The Share dialog can't be displayed if people don't have the Facebook for Android app installed. In that case we recommend you fall back to the Feed Dialog, a web dialog that doesn't require the Facebook app to be installed. To check if you can use the share dialog, you can useFacebookDialog.canPresentShareDialog:
if (FacebookDialog.canPresentShareDialog(getApplicationContext(), 
                                         FacebookDialog.ShareDialogFeature.SHARE_DIALOG)) {
    // Publish the post using the Share Dialog
    FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(this)
            .setLink("https://developers.facebook.com/android")
            .build();
    uiHelper.trackPendingDialogCall(shareDialog.present());

} else {
  // Fallback. For example, publish the post using the Feed Dialog
}
Based on the value of canPresent, you can use the share dialog or fall back to using the feed dialog, hiding the share button, etc. See the HelloFacebookSample included with the SDK for an example.
The Feed dialog is supported through the WebDialog class that contains aWebDialog.FeedDialogBuilder constructor that you can use to build the dialog. You pass in additional parameters that describe the feed story. In the sample code below, we are setting up anOnCompleteListener() to handle the completion callback and show the returned story ID if the publish is successful.
To define a new method that invokes the Feed Dialog for the Facebook instance, do the following:
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 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();
}

Step 5: Linking posts back to your native app

When your users make posts to Facebook from your app and their friends engage with these posts, you can have their friends directed to your native app (as opposed to navigating to the link in the post on the web). If they don't have your app installed, they will be taken to the Play Store to download your app. To make this happen, you need to implement deep linking. Read our deep linking guide to learn how to do this.

Troubleshooting

Can I test the Share dialog on an Android emulator?

Yes - a .apk of the Facebook app is included in the SDK download package. To install it, run:
$> adb install ~/facebook-android-sdk-3.5/bin/FBAndroid-{version}.apk

What happens if something goes wrong?

Apps should handle errors that might happen when people share content.

Share dialog fails when attaching errors, what's wrong?

If you're marking images as user_generated, make sure: + make sure images are at least 480 pixels in both dimensions + images from he app are loaded from the drawable/ directory. Loading them from the resolution-specific sub-directories can cause Android to downsize them below the 480x480 minimum size.

My app isn't getting callbacks on success / failure, what's wrong?

Make sure you're using a UiHelper instance as described in the Setup instructions.

Additional resources

See these documents for more information about using Share dialog:

API reference

Samples

Several samples included with the SDK download demonstrate the Share dialog:
  • HelloFacebookSample: shows basic usage of the Share dialog
  • RPSSample: game sample that includes sharing Open Graph actions using Share dialog
On OS X: the samples are in ~/Documents/facebook-android-sdk-{version}/samples.
On Windows: the samples are in %HOMEPATH%\facebook-android-sdk-{version}\samples.

Sharing a link using API calls

The Graph API provides a method to let you publish from your app to a user's timeline. This method requires the user to log in with Facebook in order to share, but allows you to create your own sharing interface.
You can also use this method to post a status update on the user's behalf.
For a method that doesn't require login with Facebook and makes a switch to the Facebook for Android app to allow the user to share from there, see the Share Dialog. If you are trying to publish an Open Graph story, you can read about it here.
To publish to a user's timeline using Graph API calls, you need to create a Request object that includes the path to a user's feed and information about the link the app is about to post (title, description, image, etc). Publishing will require write permissions to a user's account, so you'll pass the user through a reauthorization flow to get those permissions. Finally, if you want the people who engage with the post made from your app to be directed to your native app (instead of navigating to the posted link on the web), you will need to implement deep linking.
This document walks you through the following:

Prerequisites

Before you begin, make sure you've set up Facebook Login. Your app will need to authenticate a user before you can publish to their feed. This tutorial will build directly on the code from the Login How To.

Sample Overview

The completed sample application from this tutorial lets users log in with Facebook and publish a link to their Timeline. It builds on top of the sample from Facebook Login, adding a button that posts a hard-coded story to the user's Timeline. If the post is successful, an alert pops up with the story's ID.

Step 1: Set Up the Share Button

In the Login How To, you created a single-activity application, where the code for the UI was delegated to a Fragment class called MainFragment. From that application, add a "share" button to the UI that will be visible only if the user has logged in.
Define a new string resource for the share button. Open the Android string resource file,res/values/strings.xml, and define a new string:
<string name="share">Share</string>
Then, open your main activity's layout XML file, res/layout/main.xml, and add a <Button> to the layout just below the login button:
<Button
    android:id="@+id/shareButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textStyle="bold"
    android:gravity="center"
    android:layout_marginTop="30dp"
    android:visibility="invisible"
    android:text="@string/share"
    />
The button is set to be hidden initially, and will be visible once the user has logged in.
Now, open your fragment class, MainFragment.java, and declare a private variable for the button:
private Button shareButton;
Next, add the button to the onCreateView code so you can add functionality to it later:
shareButton = (Button) view.findViewById(R.id.shareButton);
Modify the onSessionStateChange() method in your MainFragment class file to show the publish button only when the user is authenticated:
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
    if (state.isOpened()) {
        shareButton.setVisibility(View.VISIBLE);
    } else if (state.isClosed()) {
        shareButton.setVisibility(View.INVISIBLE);
    }
}

Step 2: Add Publishing Logic

In this step, you'll add logic to publish a link (together with a name, caption, image, etc.) to Facebook.
In the MainFragment class, define a new method called publishStory(). The method will first check if the logged-in user has granted your app publish permissions; if they have not, they will be prompted to reauthorize the app and grant the missing permissions. The SDK provides methods and a standard UI to handle the reauthorization process.
Next, it creates a Request object that will be executed by a subclass of AsyncTask calledRequestAsyncTask. There are several ways to construct a Request object, depending on what you want to read from or write to the Graph API. Here, you're making a POST to the Graph API, so you pass in the current user's session, the Graph endpoint we're posting to, a Bundle of POST parameters, the HTTP method (POST) and a callback to handle the response when the call completes.
In a production app, you would add an interface to handle user input, including the ability to add a message. For simplicity, you're going to post a hard-coded story to the user's feed. Note that you will NOT add in a message in this example, as pre-filled messages are against Facebook's Platform Policies.
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) {
                JSONObject graphResponse = response
                                           .getGraphObject()
                                           .getInnerJSONObject();
                String postId = null;
                try {
                    postId = graphResponse.getString("id");
                } catch (JSONException e) {
                    Log.i(TAG,
                        "JSON error "+ e.getMessage());
                }
                FacebookRequestError error = response.getError();
                if (error != null) {
                    Toast.makeText(getActivity()
                         .getApplicationContext(),
                         error.getErrorMessage(),
                         Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(getActivity()
                             .getApplicationContext(), 
                             postId,
                             Toast.LENGTH_LONG).show();
                }
            }
        };

        Request request = new Request(session, "me/feed", postParams, 
                              HttpMethod.POST, callback);

        RequestAsyncTask task = new RequestAsyncTask(request);
        task.execute();
    }

}
Remember to import the necessary libraries (In Eclipse hit Cmd-Shift-O for Mac and Ctl-Shift-O for Windows). If given a choice during the import, select com.facebook.Session andcom.facebook.Request.
You may have noticed a few things in the code above. First, the response you get from the API call contains a GraphObject, which is the interface used by the SDK to represent objects in the graph. You can fetch the story ID from the underlying JSONObject by calling getInnerJSONObject.
You also called a helper method isSubsetOf to determine whether or not the user has granted the necessary permissions to publish the story. Define it below publishStory:
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
    for (String string : subset) {
        if (!superset.contains(string)) {
            return false;
        }
    }
    return true;
}
Then, you referenced the permissions you need and the pending authorization info withinMainFragment:
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
private boolean pendingPublishReauthorization = false;
During the reauthorization flow, the UiLifecycleHelper object handles the incoming result and updates the active session with the updated permission. This was set up earlier by overriding theonActivityResult() method.
Once the session has been updated, the onSessionStateChange() method will be called. You can check if a reauthorization was in progress and the token was updated to continue the publish story flow:
....
shareButton.setVisibility(View.VISIBLE);
if (pendingPublishReauthorization && 
        state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
    pendingPublishReauthorization = false;
    publishStory();
}
....
Now, there may be scenarios where the activity is stopped during the reauthorization flow. In this instance you'll want to save the pendingPublishReauthorization flag. Do this by modifying theonSaveInstanceState() method in MainFragment:
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(PENDING_PUBLISH_KEY, pendingPublishReauthorization);
    uiHelper.onSaveInstanceState(outState);
}
If the fragment is recreated and there is saved state, you'll want to check that and restore thependingPublishReauthorization flag. Do this in the onCreateView() method in MainFragment:
....
if (savedInstanceState != null) {
    pendingPublishReauthorization = 
        savedInstanceState.getBoolean(PENDING_PUBLISH_KEY, false);
}
return view;
....

Step 3: Connect the Share Button

To actually call publishStory() initially, we'll need to add an onClickListener to our Share button. In the onCreateView method, add a click listener to the share button that calls the publishStorymethod:
shareButton = (Button) view.findViewById(R.id.shareButton);
shareButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        publishStory();        
    }
});
Build and run the project to make sure it runs without errors. Tap the ''Log In'' button to log in with Facebook. Once authenticated, tap ''Share'' and verify that you are prompted to reauthorize the app. Afterward, you should see a success alert with the posted story ID. Check your Timeline to verify the story published correctly.

Step 4: Deep linking

When your users make posts to Facebook from your app and their friends engage with these posts, you can have their friends directed to your native app (as opposed to navigating to the link in the post on the web). If they don't have your app installed, they will be taken to the Play Store to download your app. To make this happen, you need to implement deep linking. Read our deep linking guide to learn how to do this.

Troubleshooting

If you're having trouble posting to a user's feed, the Graph API Explorer can give you more detailed error information to help you debug the issue. Be sure that you have asked for the publish actions permission, and that all the fields in your postParams variable are valid.

Additional information

Sharing Custom Stories with Open Graph

Open Graph lets apps tell stories on Facebook through a structured, strongly typed API.
Stories have the following core components:
  • An actor: the person who publishes the story, the user.
  • An action the actor performs, for example: cookrun or read.
  • An object on which the action is performed: cook a meal, run a race, read a book.
  • An app: the app from which the story is posted, which is featured alongside the story.
We provide some built in objects and actions for frequent use cases, and you can also create custom actions and objects to fit your app.
Once posted to Facebook, Open Graph stories look like this:
When people engage with these stories they can be directed to your app or your app's Play Store page, driving engagement and distribution for your app.
You can allow users to share Open Graph stories from your app using the Share Dialog or using API calls, you can learn how to do this in our Open Graph guide.

Sharing interfaces

On Android, apps can share stories in several ways. This section describes those, including the advantages and disadvantages of each along with links to sample code and reference documentation.

Share dialog

The Share dialog is the newest way for people to share stories from apps. It lets apps share rich Open Graph stories and has full support for the Facebook post model, including giving people the ability to tag friends and places. The Share dialog is fully native and provides people the best experience of any of the sharing options. Share dialog can be used by anyone who uses your app, regardless of whether they use Facebook Login to connect an app to their Facebook account.
Advantages
  • 100% native for a great, fast share experience
  • Support for sharing Open Graph stories
  • Does not require Facebook Login
Disadvantages
  • Needs the Facebook for Android app installed in the device. Apps that use the Share dialog may choose to fall back to the Feed dialog on devices when the Facebook app is not installed
Links

Feed dialog

The Feed dialog is a web-based dialog that works on all devices at the expense of an optimum experience for people using your apps. Since the Feed dialog opens a web page for sharing, it must start by asking people for their Facebook credentials in order to verify their identity, which disrupts the sharing flow. People are also asked to re-enter their credentials over time as their password changes. The Feed dialog does not support Open Graph and supports only the basic post model which includes a link, title/description text and an image. However, the Feed Dialog makes it a perfect fallback if you're using the Share Dialog as it works everywhere.
Advantages
  • Available on any device
Disadvantages
  • Does not support sharing Open Graph stories
  • Web-based dialog does not offer best experience for people using app
  • People using app must enter their Facebook credentials before sharing
Links

Graph API

The Graph API is the most powerful and flexible way for apps to share stories to Facebook. People must use Facebook Login to connect the app to their Facebook account, and then the app must requestpublish_actions permission. This gives the app permission to use the Graph API to post stories on behalf of people using the app. With Graph API access, apps can employ a tailor-made sharing experience and have the ability to tag friends and places and set the audience for a post.
Advantages
  • Lets apps build fully custom sharing experiences
  • Supports sharing Open Graph stories
Links

Best practices

For the best sharing experience, apps should use the share dialog by default and fall back to the web-based feed dialog if the Facebook app is not installed on the device.
Learn how to do this in the following section of this document:
The feed dialog does not support posting Open Graph stories. When an app that/'s using the share dialog to post an Open Graph story falls back to the feed dialog, it should transform the Open Graph story into a simple link share.
Was this document helpful?