Why doesn't Android Facebook interface work with snippets?

I am switching the Android Facebook code from Activity to Fragment . Before the switch, everything worked fine, but now the onComplete() callback does not work.

Does Facebook code work with Snippets , or am I doing something wrong?

Here's the source code (in SherlockActivity ):

 if (!mFacebook.isSessionValid()) { mFacebook.authorize(MyActivity.this, permissions, new DialogListener() { @Override public void onComplete(Bundle values) { ... } // CALLED AS EXPECTED } } 

And here is the new code (in SherlockFragment):

 if (!mFacebook.isSessionValid()) { mFacebook.authorize(getActivity(), permissions, new DialogListener() { @Override public void onComplete(Bundle values) { ... } // DOES NOT GET CALLED } } 

Both the activity and the fragment include the same onActivityResult () as required by Facebook:

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mFacebook.authorizeCallback(requestCode, resultCode, data); } 

Thanks for your help!

EDIT: A similar question is asked here where the accepted answer is changing Fragment to FragmentActivity . But I don’t see how this helps, since then it is no longer a Fragment (which I need for other reasons). Suggestions?

EDIT 2: I implemented my own decision. See below.

+2
source share
5 answers

As far as I can tell, the auth API for Facebook does not support Snippets . In particular, the onComplete() callback from the Facebook call authorize() works with Activities , but not with Snippets .

So, I have put together an easy way to bypass Fragments . The solution depends on the fact that onActivityResult() also called in the parent Activity when the authorize() call completes, so you can use it to configure a separate callback mechanism for the Snippet .

First set up the variable in the parent Activity to transfer the name of the Fragment , say

 TargetFragment mTargetFragment; 

You can initialize it when the Fragment is first created this way:

 @Override public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); String fragmentSimpleName = fragment.getClass().getSimpleName(); if (fragmentSimpleName.equals("TargetFragment")) mTargetFragment = (TargetFragment)fragment; } 

Then add a couple lines of the onActivityResult () function:

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (mTargetFragment != null) mTargetFragment.myCallBack(requestCode, resultCode, data); } 

Now you can simply simulate the code that you usually put in the onComplete () callback in the new myCallBack () function:

 public void myCallBack(int requestCode, int resultCode, Intent data) { mFacebook.authorizeCallback(requestCode, resultCode, data); // other code from your onComplete() function ... } 

Hope this helps someone else. Hooray!

+12
source

I downloaded the latest version of the SDK for Facebook and I have the same problem, gcl1 solution works fine, but I have to do more things in activity so I did it on parent activity:

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (mTargetFragment != null) { mTargetFragment.onActivityResult(requestCode, resultCode, data); } } 
+5
source

The Facebook SDK does not work with fragment, but works with FragmentActivity. Therefore you need to:

  • Catch FB registration information in onActivityResult () in the parent FragmentActivity.
  • Transferring Activity Results to Your Child

Example:

one.

 public class MainActivity extends FragmentActivity(){ /* catch FACEBOOK login info and call onFBLoginActivityResult() to pass it to FacebookFrragment*/ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); android.support.v4.app.FragmentManager fm = getSupportFragmentManager(); FacebookFragment fbfragment= (FacebookFragment ) fm.findFragmentByTag("facebookfragment"); selectPKEConfigFragment.onFBLoginActivityResult(requestCode, resultCode, data); } } 

2.

 public class FacebookFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // ........... // start Facebook Login Session.openActiveSession(getActivity(), true, new Session.StatusCallback() { // callback when session changes state @Override public void call(Session session, SessionState state, Exception exception) { if (session.isOpened()) { // make request to the /me API Request.executeMeRequestAsync(session, new Request.GraphUserCallback() { // callback after Graph API response with user object @Override public void onCompleted(GraphUser user, Response response) { if (user != null) { // TextView welcome = (TextView) findViewById(R.id.welcome); // welcome.setText("Hello " + user.getName() + "!"); Log.i(TAG,"User: " + user.getName()); } else Log.i(TAG,"User: null"); } }); } else Log.i(TAG,"session closed"); } }); } /* * replace onActivityResult */ public void onFBLoginActivityResult(int requestCode, int resultCode, Intent data){ Log.i(TAG,"Activity result SelectPKEConfig"); Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data); } 
+2
source

Actually, if you look at Facebook Docs for Android , you will see that a fragment is used in the login example.

There is a LoginButton widget that provides the Facebook SDK, and it has a setFragment method, and you pass in the target fragment with which you want to use the login function.

In fragment layout

Add the login button that the Facebook SDK provides.

  <com.facebook.widget.LoginButton android:id="@+id/facebook_login_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="30dp" /> 

In your fragment

Create the UiLifecycleHelper and StatusCallback objects in your fragment.

 private UiLifecycleHelper uiHelper; private Session.StatusCallback callback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { onSessionStateChange(session, state, exception); } }; 

Add a method to handle user state changes.

 private void onSessionStateChange(Session session, SessionState state, Exception exception) { if (state.isOpened()) { Log.i("LoginFragment", "Logged in..."); Log.i("LoginFragment", session.getAccessToken()); doAnythingWithTheFacebookToken(session.getAccessToken()); } else if (state.isClosed()) { // this part is called when user login fails Log.i("LoginFragment", "Logged out..."); } } 

Override fragment lifecycle methods

 @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) { // inflate your fragment view facebookLoginButton = (LoginButton) view.findViewById(R.id.facebook_login_button); facebookLoginButton.setFragment(this); } @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 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); } 

Result

Usually you need to override onActivityResult in your activity, but calling setFragment () on the Facebook Login Button allows your snippet to get the result in its own onActivityResult .

If you want to use another button (e.g. your own button):

  • hide facebookloginbutton in layout

  • call executeClick () on facebookLoginButton inside the onclick listener of your actual button

What is it.

+1
source

We do not need to configure onActivityResult inside the main activity of the fragment class and inner fragment. Just put the code below inside the main action that contains your snippet and make the rest of the facebook sdk code inside the snippet ... it's that simple.

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Session.getActiveSession().onActivityResult(ChatScreen.this, requestCode, resultCode, data); } 
0
source

Source: https://habr.com/ru/post/1501249/


All Articles