Most of the steps depicted here can be found on
Facebook Developers page but sharing a photo
while showing the share dialog isn't fully documented.
Download SDK
Download the Facebook SDK and extract it.
Setup Workspace
Add the Facebook SDK project to your workspace and link the library to your project.
Register App on Facebook
Follow
these steps to create a Facebook app and get the Application Id.
Android Manifest
Add these elements to your app Manifest file inside the application element and replace the 123456789456789 of the provider with the application id you got from the facebook page.
<activity android:name="com.facebook.LoginActivity" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<provider android:authorities="com.facebook.app.NativeAppCallContentProvider123456789456789" android:name="com.facebook.NativeAppCallContentProvider" android:exported="true" />
The provider was what I was missing from my solution resulting on the photo being published without showing any dialog to the user.
Don't forget to add the facebook_app_id string in your string.xml file.
Initialization
I ended up using Android Simple Facebook library to login the user if necessary since it's really easy to use.
private Permission[] permissions = new Permission[] { Permission.PUBLISH_ACTION };
public initialization(String appId, String appNamespace, Bundle savedInstanceState) {
// Facebook SDK initialization
uiHelper = new UiLifecycleHelper(this, null /*statusCallback*/);
uiHelper.onCreate(savedInstanceState);
// Simple Facebook Library initialization
SimpleFacebookConfiguration configuration = new SimpleFacebookConfiguration.Builder().setAppId(appId).setNamespace(appNamespace).setPermissions(permissions).build();
SimpleFacebook.setConfiguration(configuration);
}
Use the status callback to get Facebook session status
It is also needed to attach some lifecycle events to these libraries.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
@Override
protected void onResume() {
super.onResume();
uiHelper.onResume();
mSimpleFacebook = SimpleFacebook.getInstance(activity);
}
@Override
protected void onPause() {
super.onPause();
uiHelper.onPause();
}
@Override
protected void onDestroy() {
uiHelper.onDestroy();
super.onDestroy();
}
Login user
Before actually posting the user is requested to be logged in and authorize the app. Since we're using the Facebook SDK it requires the Facebook App to be installed on the device. Since the user will already be logged in the Facebook App this post will not request the user to login again. The first post will, however, request permission for your app to post in the user timeline.
As stated above, I've used Simple Facebook library for login.
public void checkFacebookLogin(final File photo) {
if (facebook.isLoggedIn()) {
postPhoto(photo);
} else {
facebook.logIn(new OnLoginListener() {
@Override
public void onFail(String result) {}
@Override
public void onException(Throwable exception) {}
@Override
public void onThinking() {}
@Override
public void onNotAcceptingPermissions(Type type) {}
@Override
public void onLogin() {
postPhoto(photo);
}
});
}
}
On production code you should actually handle the other events.
Post Photo
Actually post the photo.
public void postPhoto(File photo) {
if (FacebookDialog.canPresentShareDialog(this, FacebookDialog.ShareDialogFeature.PHOTOS)) {
FacebookDialog shareDialog = new FacebookDialog.PhotoShareDialogBuilder(this).addPhotoFiles(Arrays.asList(photos)).build();
uiHelper.trackPendingDialogCall(shareDialog.present());
}
}
Since the WebDialog provided by the Facebook SDK doesn't post photos it looks like we're stuck with this method.