Instantly share code, notes, and snippets.
Created
December 17, 2013 15:48
-
Star
2
(2)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save sgdesmet/8007039 to your computer and use it in GitHub Desktop.
Post messages to Facebook with the Android Facebook SDK (v3.6)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.sgdesmet.android; | |
import android.content.Intent; | |
import android.os.Bundle; | |
import android.util.Log; | |
import com.facebook.*; | |
import com.facebook.widget.FacebookDialog; | |
import com.facebook.widget.WebDialog; | |
import java.io.Serializable; | |
import java.util.Arrays; | |
import java.util.List; | |
import com.github.sgdesmet.android.R; | |
import org.apache.commons.lang3.StringUtils; | |
import org.jetbrains.annotations.NotNull; | |
import org.jetbrains.annotations.Nullable; | |
import android.support.v4.app.Fragment; | |
/** | |
* Facebook login and sharing example | |
* | |
* @author sgdesmet | |
*/ | |
public abstract class AbstractShareFragment extends Fragment { | |
private static final List<String> FB_PERMISSIONS = Arrays.asList( "publish_actions" ); | |
private static final String TAG = AbstractShareFragment.class.getName(); | |
private static final String PENDING_MESSAGE = "pending_message"; | |
private UiLifecycleHelper fbUiHelper; | |
private FbMessage pendingMessage; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate( savedInstanceState ); | |
fbUiHelper = new UiLifecycleHelper( getActivity(), new SessionCallback() ); | |
fbUiHelper.onCreate( savedInstanceState ); | |
if (savedInstanceState != null) | |
pendingMessage = (FbMessage) savedInstanceState.getSerializable( PENDING_MESSAGE ); | |
} | |
@Override | |
public void onActivityResult(int requestCode, int resultCode, Intent data) { | |
fbUiHelper.onActivityResult( requestCode, resultCode, data, new ShareDialogCallbackWrapper() ); | |
super.onActivityResult( requestCode, resultCode, data ); | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
fbUiHelper.onResume(); | |
} | |
@Override | |
public void onSaveInstanceState(Bundle outState) { | |
super.onSaveInstanceState( outState ); | |
fbUiHelper.onSaveInstanceState( outState ); | |
outState.putSerializable( PENDING_MESSAGE, pendingMessage ); | |
} | |
@Override | |
public void onPause() { | |
super.onPause(); | |
fbUiHelper.onPause(); | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
fbUiHelper.onDestroy(); | |
} | |
/** | |
* General share | |
* @param name | |
* @param description | |
* @param url | |
* @param imageUrl | |
*/ | |
protected void share(@NotNull final String name, @NotNull final String description, @Nullable final String url, | |
@Nullable final String imageUrl) { | |
shareWithFB( name, description, url, imageUrl ); | |
} | |
/** | |
* Share with facebook. | |
*/ | |
public void shareWithFB(@NotNull final String name, @NotNull final String description, @Nullable final String url, | |
@Nullable final String imageUrl) { | |
if (getActivity() == null) | |
return; | |
pendingMessage = new FbMessage( name, description, url, imageUrl ); | |
// check if user logged in / has permission to post | |
Session session = Session.getActiveSession(); | |
if (session == null) { | |
session = new Session.Builder( getActivity() ).setApplicationId( getString( R.string.app_id ) ).build(); | |
Session.setActiveSession( session ); | |
} | |
// if the session is not open or opening, we need to open it | |
if (!session.getState().isOpened() && session.getState() != SessionState.OPENING) { | |
Session.OpenRequest openRequest = new Session.OpenRequest( this ); | |
openRequest.setPermissions( FB_PERMISSIONS ); | |
openRequest.setLoginBehavior( SessionLoginBehavior.SSO_WITH_FALLBACK ); | |
session.openForPublish( openRequest ); | |
return; | |
} | |
// if the session is open, try to post message (else we wait for session callback) | |
if (session.isOpened()) { | |
if (hasPublishPermission()) { | |
// We can do the action right away. | |
postMessage( pendingMessage ); | |
pendingMessage = null; | |
} else { | |
// We need to reauthorize, then complete the action when we get | |
// called back. | |
// requestCode -1 means use the default facebook value | |
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest( this, | |
FB_PERMISSIONS ).setRequestCode( -1 ).setLoginBehavior( SessionLoginBehavior.SSO_WITH_FALLBACK ); | |
session.requestNewPublishPermissions( newPermissionsRequest ); | |
} | |
} | |
} | |
private boolean hasPublishPermission() { | |
Session session = Session.getActiveSession(); | |
return session != null && session.isOpened() && session.getPermissions().contains( "publish_actions" ); | |
} | |
protected void postMessage(@NotNull final FbMessage message) { | |
// check if we can use native FB app, or need to fall back to web-based dialog | |
if (getActivity() != null && FacebookDialog.canPresentShareDialog( getActivity().getApplicationContext(), | |
FacebookDialog.ShareDialogFeature.SHARE_DIALOG )) { | |
postUsingShareDialog( message ); | |
} else if (getActivity() != null) { | |
postUsingWebDialog( message ); | |
} | |
} | |
protected void postUsingShareDialog(@NotNull final FbMessage message) { | |
FacebookDialog.ShareDialogBuilder builder = new FacebookDialog.ShareDialogBuilder( getActivity() ).setName( message.name ) | |
.setDescription( | |
message.description ); | |
if (StringUtils.isNotBlank( message.url )) | |
builder.setLink( message.url ); | |
if (StringUtils.isNotBlank( message.imageUrl )) | |
builder.setPicture( message.url ); | |
fbUiHelper.trackPendingDialogCall( builder.build().present() ); | |
} | |
protected void postUsingWebDialog(@NotNull final FbMessage message) { | |
Bundle params = new Bundle(); | |
params.putString( "name", message.name ); | |
params.putString( "description", message.description ); | |
if (StringUtils.isNotBlank( message.url )) | |
params.putString( "link", message.url ); | |
if (StringUtils.isNotBlank( message.imageUrl )) | |
params.putString( "picture", message.imageUrl ); | |
WebDialog feedDialog = (new WebDialog.FeedDialogBuilder( getActivity(), Session.getActiveSession(), params )).setOnCompleteListener( | |
new WebDialogCallbackWrapper() ).build(); | |
feedDialog.show(); | |
} | |
@NotNull | |
protected abstract ShareCallback getShareCallback(); | |
public static interface ShareCallback { | |
public void success(); | |
public void cancelled(); | |
public void error(); | |
} | |
/** | |
* Facebook callback when sharing with native dialog | |
*/ | |
private class ShareDialogCallbackWrapper implements FacebookDialog.Callback, Serializable { | |
@Override | |
public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data) { | |
Log.e( "Activity", String.format( "Error: %s", error.toString() ) ); | |
getShareCallback().error(); | |
} | |
@Override | |
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) { | |
if (data != null && StringUtils.isNotBlank( data.getString( "FacebookDialog.getNativeDialogPostId" ) )) | |
getShareCallback().success(); | |
else | |
getShareCallback().cancelled(); | |
} | |
} | |
/** | |
* Facebook callback when sharing with web-based (fallback) dialog | |
*/ | |
private class WebDialogCallbackWrapper implements WebDialog.OnCompleteListener, Serializable { | |
@Override | |
public void onComplete(final Bundle values, final FacebookException error) { | |
if (error == null) { | |
// When the story is posted, echo the success | |
final String postId = values.getString( "post_id" ); | |
if (postId != null) { | |
getShareCallback().success(); | |
} else { | |
// User clicked the Cancel button | |
getShareCallback().cancelled(); | |
} | |
} else if (error instanceof FacebookOperationCanceledException) { | |
// User clicked the "x" button | |
getShareCallback().cancelled(); | |
} else { | |
// Generic, ex: network error | |
getShareCallback().error(); | |
} | |
} | |
} | |
private class SessionCallback implements Session.StatusCallback, Serializable { | |
@Override | |
public void call(final Session session, final SessionState state, final Exception exception) { | |
Log.d( AbstractShareFragment.TAG, "Session state changed to: " + state ); | |
if (pendingMessage != null && session != null) { | |
shareWithFB( pendingMessage.name, pendingMessage.description, pendingMessage.url, pendingMessage.imageUrl ); | |
} | |
} | |
} | |
public static class FbMessage implements Serializable { | |
@NotNull | |
final String name; | |
@NotNull | |
final String description; | |
@Nullable | |
final String url; | |
@Nullable | |
final String imageUrl; | |
public FbMessage(@NotNull final String name, @NotNull final String description, @Nullable final String url, | |
@Nullable final String imageUrl) { | |
this.name = name; | |
this.description = description; | |
this.url = url; | |
this.imageUrl = imageUrl; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment