Using Share Dialog of Facebook on Fragments and Viewpager - android

I have implemented a tab layout using fragments and viewpager. However, on my fifth tab, I want to share where the user is on the google maps, which is on the third tab. This is my code for my "Share on Facebook" tab.
TabFour.java
public class TabFour extends Fragment {
private UiLifecycleHelper uiHelper;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_tab_four, container, false);
return rootView;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public 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!");
}
});
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
#Override
public 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();
}
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
// TODO Auto-generated method stub
}
};
}
However, there is an error on this line:
uiHelper = new UiLifecycleHelper(this, callback);
and the error says:
The constructor UiLifecycleHelper(TabFour, Session.StatusCallback) is undefined
What could be the possible problem? There is no other methods for the UiLifecycleHelper on Facebook Developers. Please help. Thanks!

Document say :
public UiLifecycleHelper(Activity activity, Session.StatusCallback callback)
Creates a new UiLifecycleHelper.
Parameters
activity: the Activity associated with the helper. If calling from a Fragment, use Fragment.getActivity()
callback: the callback for Session status changes, can be null
For more information you can check this link:
https://developers.facebook.com/docs/reference/android/current/UiLifecycleHelper

That's because the this you're using refers to the Fragment, not an Activity, which is what the constructor requires. Try replacing this with getActivity (or if you're using ABS, getSherlockActivity)

I know I am replying late, but I hope this will help all others..
In your fragment class call this..
FragmentActivity activity=getActivity();
Now in UiLifeCycleHelper constructor, pass activity instead of "this"
uiHelper=new UiLifeCycleHelper(activity, CallBack);

On Facebook SDK 4.x UiLifecycleHelper is replaced with CallbackManager. To implement Facebook Share Dialog in a fragment now is easier:
1) OnCreateView in your fragment class:
CallbackManager mCallbackManagerFacebook;
// Facebook Share
mCallbackManagerFacebook = CallbackManager.Factory.create();
2) In your app class:
// Facebook
FacebookSdk.sdkInitialize(getApplicationContext());
3) Override onActivityResult in your fragment class with:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallbackManagerFacebook.onActivityResult(requestCode, resultCode, data);
}
4) For example, you have a button that OnClickListener the user can share a photo:
ImageButton fbBtn = (ImageButton) v.findViewById(R.id.facebookHomeDetailButton);
fbBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProgressBar.setSpinSpeed(10);
mProgressBar.setVisibility(View.VISIBLE);
mProgressBar.spin();
if (ShareDialog.canShow(ShareLinkContent.class)) {
ParseFile fileObject = (ParseFile)mParseObjectsList.get(mPosition).get("thumbnail");
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Log.d("test", "We've got data in data.");
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
SharePhoto photo = new SharePhoto.Builder()
.setBitmap(bitmap)
.build();
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(photo)
.build();
mShareDialogFacebook.show(getActivity(), content);
mProgressBar.stopSpinning();
mProgressBar.setVisibility(View.INVISIBLE);
} else {
Log.d("test", "There was a problem downloading the data.");
}
}
});
} else {
showDialogWithOk("¡Ooops!\nParece que no tienes Facebook instalado en tu dispositivo. Para compartir tendrías que instalar esta aplicación en tu dispositivo.\n¡Gracias!");
}
}
});
5) That´s all. I hope that this code can help.

Related

Android Facebook Login onActivityResult

I use fragment for facebook login. Normally everything goes fine. But in first time , when user login with facebook s/he redirected to facebook page and give permission to program but then (despite i use CallbackManager.onActivityResult) , program cannot handle the callback and stay background. How can i handle the callback ??
Relative code snippet:
public void onCreate(Bundle savedInstanceState) {
FacebookSdk.sdkInitialize(getActivity().getApplicationContext());
super.onCreate(savedInstanceState);
callbackManager = CallbackManager.Factory.create();
}
public void onResume() {
Log.i("tago" , "onResume");
super.onResume();
Profile profile = Profile.getCurrentProfile();
if (profile != null) {
tumisim = profile.getName();
firstname = profile.getFirstName();
lastname = profile.getLastName();
sharedtumisimkaydet(tumisim);
sharedfirstnamekaydet(firstname);
sharedlastnamekaydet(lastname);
}
}
public void onStop() {
super.onStop();
getActivity().finish();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.facebookfragment, container, false);
int[] taniticiresimler = {R.mipmap.aciklama,R.mipmap.dene_uc,R.mipmap.yenigus,R.mipmap.galp};
CustomPagerAdapter pagerAdapter = new CustomPagerAdapter(getActivity(),taniticiresimler);
FadingIndicator indicator = (FadingIndicator)view.findViewById(R.id.circleIndicator);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
viewPager.setAdapter(pagerAdapter);
indicator.setViewPager(viewPager);
indicator.setFillColor(Color.BLUE);
indicator.setStrokeColor(Color.BLACK);
indicator.setRadius(15f);
LoginButton loginButton = (LoginButton) view.findViewById(R.id.login_button);
loginButton.setReadPermissions(Arrays.asList("user_friends", "public_profile", "email"));
loginButton.setFragment(this);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
profile = Profile.getCurrentProfile();
if (profile.getId() != null) {
facebookID = profile.getId();
String a = sharedFacebookIDAl();
if (a.equals("defaultfacebookID")) {
sharedilkgiriskaydet(true);
}else if(!a.equals(facebookID)){
sharedilkgiriskaydet(true);
}else{
sharedilkgiriskaydet(false);
}
sharedfacebookIDkaydet(facebookID);
KullaniciProfilCek kPC = new KullaniciProfilCek();
kPC.execute(profile.getId());
}
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
email = object.getString("email");
sharedemailkaydet(email);
cinsiyet = object.getString("gender");
sharedcinsiyetkaydet(cinsiyet);
coverphotourl = object.getJSONObject("cover").getString("source");
sharedcoverphotourlkaydet(coverphotourl);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "email,gender,cover");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Toast.makeText(getActivity(), "Facebook Login iptal edildi", Toast.LENGTH_LONG).show();
}
#Override
public void onError(FacebookException error) {
Toast.makeText(getActivity(), "Facebook Login hata oluşturdu", Toast.LENGTH_LONG).show();
}
});
return view;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
Log.i("tago" , "geri geldi");
}
Inside the fragment you cannot listen onActivityResult directly. Listen the results in the onActivityResult inside your Activity. Put the code below in the Activity which holds the fragment.
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
if (fragment != null) {
fragment.onActivityResult(requestCode, resultCode, intent);
}
}
and then the OnActivityResult() inside the fragment will work.
You are using onActivityResult() wrong - you do not call super class implementation unless you know you need to. This got nothing with the need of calling super i.e. in onCreate() etc. Here's documentation you should read now:
https://developer.android.com/training/basics/intents/result.html

Android Login button not calling onActivityResult or callback methods

I'm trying to implement the Facebook login button in my Android app, this is what I've done so far:
public class LoginFragment extends BaseFragment {
private View mView;
private CallbackManager mCallbackManager;
private LoginButton mFBLoginButton;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
FacebookSdk.sdkInitialize(getActivity());
mCallbackManager = CallbackManager.Factory.create();
mView = inflater.inflate(R.layout.login, container, false);
mFBLoginButton = (LoginButton) mView.findViewById(R.id.login_facebook_button);
mFBLoginButton.setReadPermissions("public_profile", "user_friends","user_birthday","user_about_me","email");
mFBLoginButton.setFragment(this);
mFBLoginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d("LoginFragment", "UserId: " + loginResult.getAccessToken().getUserId());
}
#Override
public void onCancel() {
Log.d("LoginFragment", "Operation Canceled");
}
#Override
public void onError(FacebookException e) {
e.printStackTrace();
}
});
return mView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
getBaseActivity().displayToastMessage("Hey");
mCallbackManager.onActivityResult(requestCode, resultCode, data);
}
I also added the Facebook activity and Id in the application manifest. The app runs fine and when I click the Login button it takes me to the Facebook dialog. The problem here is that none of the callback methods get executed i.e. onSuccess(), onCancel() and onError(). Also the onActivityResult() is not executed either. Please tell me if I missed something
After a long inspection, I found out that I set the noHistory for the activity holding the fragment to true. This prevented from going back to the activity again once the authentication was successful which led to onActivityResult() not being called.
I too have this issue,But is solved by adding method in parent activities OnActivityResult function,to fragment method.
#Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
try {
String fragmentSimpleName = fragment.getClass().getSimpleName();
if (fragmentSimpleName.equals("Fragment1")){
frag = (Fragment1) fragment;
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// facebook.authorizeCallback(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
try {
if (frag != null){
frag.myCallBack(requestCode, resultCode, data);
}
} catch (Exception e) {
e.printStackTrace();
}
}

Facebook share dialog PostId is null

I am sharing a video on FB via share dialog in Android. The sharing works perfectly fine. However, FB post id returns null. The callback returns even before the video is uploaded. Please let me know, if I missing something. Below is my code.
public class TestFragment extends Fragment {
private CallbackManager callbackManager;
private ShareDialog shareDialog;
public TestFragment() {
// Required empty public constructor
}
public static TestFragment newInstance(String path, String json) {
TestFragment fragment = new TestFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getActivity());
callbackManager = CallbackManager.Factory.create();
shareDialog = new ShareDialog(this);
// this part is optional
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
Timber.d("result.getPostId() :: " + result.getPostId());
}
#Override
public void onCancel() {
Timber.d("Facebook : Cancelled");
}
#Override
public void onError(FacebookException e) {
Timber.d(e.getMessage());
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, container, false);
ButterKnife.inject(this, view);
return view;
}
#OnClick(R.id.facebookShare)
public void share() {
Timber.d("share button pressed");
if (ShareDialog.canShow(ShareVideoContent.class)) {
Timber.d("showing share dialog");
shareDialog.show(getVideoContent());
} else {
Timber.d("unable to show the share dialog");
}
}
private ShareVideoContent getVideoContent() {
Timber.d(mVideoMetadata.getVideoId());
ShareVideo shareVideo = new ShareVideo.Builder()
.setLocalUrl(Uri.parse("... file ..."))
.build();
ShareVideoContent content = new ShareVideoContent.Builder()
.setVideo(shareVideo)
.build();
return content;
}
#Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
}
shareDialog.show(shareContent, ShareDialog.Mode.FEED);
Set mode to ShareDialog.Mode.FEED.
It's working for me .
Here's example
When Login Success With Facebook Then Call This Method
shareOnFacebook()
private void shareOnFacebook(){
ShareLinkContent shareContent = new ShareLinkContent.Builder()
.setContentTitle("The Simpson!")
.setContentUrl(Uri.parse("http://www.codecube.in/airbucks-project"))
.build();
mFacebookShareDialog.show(shareContent, ShareDialog.Mode.FEED);
mFacebookShareDialog.registerCallback( this.callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
Log.v("MyApp", "Share success!"); //Showed if I press the share or the cancel button
String postID = result.getPostId();
Log.v("MyApp", "Share success!" +result.getPostId());
}
#Override
public void onCancel() {
Log.v("MyApp", "Share canceled"); //Only showed when I press the close button
}
#Override
public void onError(FacebookException e) {
Log.v("MyApp","Share error: " + e.toString());
}
});
mFacebookShareDialog.show(shareContent, ShareDialog.Mode.FEED);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}

Android Facebook SDK 3.0 Session State "Opening"

I am integrating Facebook's Login using their documentation. I am running into an issue where when i click the Facebook Login Widget the session changes to "Opening" and the app crashes
My Layout for Facebook button
<com.facebook.widget.LoginButton
android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
The Fragment is
public class FacebookFragment extends Fragment {
private static final String TAG = "FacebookFragment";
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(final Session session, final SessionState state, final Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
LoginButton authButton = (LoginButton) view.findViewById(R.id.authButton);
authButton.setFragment(this);
authButton.setReadPermissions(Arrays.asList("user_likes", "user_status"));
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
Session session = Session.getActiveSession();
if (session != null &&
(session.isOpened() || session.isClosed()) ) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
else
Log.i(TAG, session.toString());
}
}
and in the activity i have implemented the required onActivityResult and retrieving the fragment
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new FacebookFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mainFragment)
.commit();
} else {
// Or set the fragment from restored state info
mainFragment = (FacebookFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
I thought maybe the issue lies with the Key Hash, but i followed the directions completely from the answer posted on this question Key hash for Android-Facebook app
Any lead on how to get the state to "Opened" would be greatly appreciated
The problem was in having android:clearTaskOnLaunch="true" on the activity that was doing the facebook login. The OnActivityResult was not able to be called. I was able to get a Exception when i ran the application in debug mode.
Add session.addCallback(callback) in your onResume():
super.onResume();
Session session = Session.getActiveSession();
session.addCallback(callback);

Facebook Android SDK 3.0 always returns OPENING when logging in

I followed the instructions at https://developers.facebook.com/docs/howtos/androidsdk/3.0/login-with-facebook/. When I touch the "Log In"-button, the session state is OPENING - always. When I try to post a story to the user's wall I get an error stating
"Session: an attempt was made to request new permissions for a session
that has a pending request."
Here is my code:
public class MainFragment extends Fragment {
private static final String TAG = "MainFragment";
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (state.isOpened()) {
Log.d(TAG, "Logged in...");
} else if (state.isClosed()) {
Log.d(TAG, "Logged out...");
} else {
Log.d(TAG, "Unknown state: " + state);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
// For scenarios where the main activity is launched and user
// session is not null, the session state change notification
// may not be triggered. Trigger it if it's open/closed.
Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed())) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.facebook_login, container, false);
LoginButton authButton = (LoginButton) view
.findViewById(R.id.authButton);
authButton.setFragment(this);
return view;
}
private boolean isSubsetOf(Collection<String> subset,
Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
private static final List<String> PERMISSIONS = Arrays
.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
private boolean pendingPublishReauthorization = false;
public 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();
}
}
}
What's wrong?
Edit: I'd also like to mention that the text on the "Log In"-Button doesn't change. I don't get an error while authenticating, but as far as I read it should change to "Log Out".
It wasn't easy to figure this out. :-)
If you actually check out exception in onSessionStateChange(), you'll see that it's not really simply stuck in OPENING. That exception contains: java.lang.UnsupportedOperationException: Session: an attempt was made to open a session that has a pending request.
The reason I finally found was that onActivityResult() wasn't called. It's its responsibility to call back to uiHelper and that call will call the finishing part of the login, so it if isn't called, the state stays OPENING forever. Apart from the obvious pieces of advice above, this is what I found and they are all needed for the login to work:
Make sure you use both a fragment and an activity, as described in the FB documentation. Even if the doc hints at an activity being enough, it isn't. You need both even if the activity has nothing else but calling the single fragment.
Make sure you have no history set for the activity (neither in the manifest nor in code).
Make sure you override the fragment's onActivityResult() as per the documentation. And make sure you override the same in the activity as well:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
Yes, this seems strange but it doesn't work without it.
Finally this works for me. The key points was to add
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
and
loginBtn.setFragment(this);
loginBtn.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
#Override
public void onUserInfoFetched(GraphUser user) {
graphUser = user;
}
});
Code inside Fragment:
private GraphUser graphUser;
private UiLifecycleHelper uiHelper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.test_frame, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.getMeBtn).setOnClickListener(this);
LoginButton loginBtn = (LoginButton) view.findViewById(R.id.loginBtn);
loginBtn.setFragment(this);
loginBtn.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
#Override
public void onUserInfoFetched(GraphUser user) {
graphUser = user;
}
});
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
updateUI();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
updateUI();
}
private void updateUI() {
if (graphUser != null) {
Log.d("TEST", graphUser.getFirstName());
}
}
#Override
public void onClick(View view) {
Session session = Session.getActiveSession();
Log.d("TEST", "session.getState() = " + session.getState());
if (session.getState().isOpened()) {
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
updateUI();
}
}
});
}
}
I had the same issue. The state was always OPENING. Turns out that #Gabor was wright.
When the session state is OPENING a method onActivityResult gets called, that's for sure.
If you are using a fragment, onActivityResult is called in the ACTIVITY that holds the fragment, and not in the fragment. That is due to the passed context etc.
So i did it like this:
Check what onActivityResults gets called (by logcat) - just to make sure
In that method add a line Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); Notice that the parameter this is an activity context. OR Use the UiLifecycleHelper's onActivityResult method, like this:
UiHelper.onActivityResult(requestCode, resultCode, data);More about it here
If anyone else is still having this issue it can be caused by overriding onActivityResult in the Activity and not calling the super method.
Activity
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
/* other code here */
super.onActivityResult(requestCode, resultCode, data);
}
Fragment
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
uiHelper.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
You should implement onActivityResult in the activity not in the fragment.
Worked for me.
Yet another reason this might occur (as it has for me) is when you're using getChildFragmentManager() - onActivityResult is not passed to nested Fragments, due to a bug.
This (having the hosting Fragment pass its received onActivityResult to all children) is what helped me.
My Activity's onActivityResult is being invoked... So I did a very very bad hacking there:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == 64206) //Bad hacking
if(df!=null)
df.onActivityResult(requestCode, resultCode, data);
df is my fragment. That made the session get open... this is friggin crazy. Very interested to find a better solution for this.
In my case, I was trying to change the fragment class from
android.support.v4.app.Fragment to android.app.Fragment (I was not supporting pre API-11 Android versions) and omitted the FBAuthButton.setFragment(this); statement. That was actually causing the problem.
I experienced the same problem, I uninstalled my app and reinstalled and it worked!

Categories

Resources