Question

I have a fragment that uses facebook's UserSettingsFragment for login. Now I want that fragment to get the UserID after login and just after that it should replace that fragment with a new fragment.

I'm getting the facebook-UserID using a newMeRequest which gets executed by executeBatchAsync. The newMeRequest gets executed in the call method of the UserSettingsFragment's StatusCallback if the Session is OPENED. I'm getting the UserID and want to replace the fragment in the OnCompleted method of the newMeRequest.

Mostly my app crashes in the line i want to replace the fragment. I think it depends on the asynchronous execution of the request.

Here is the code of my fragment class:

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.model.GraphUser;
import com.facebook.widget.UserSettingsFragment;

public class LoginFacebookFragment extends Fragment {

    private UserSettingsFragment mUsrStFmt;
    private DataSet mDataSet;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_facebook, container, false);
        mDataSet = DataSet.getInstance();
        mUsrStFmt = (UserSettingsFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.login_fragment);
        mUsrStFmt.setSessionStatusCallback(new Session.StatusCallback() {
            @Override
            public void call(final Session session, SessionState state, Exception exception) {
                Log.d("LoginFacebookFragment", String.format("New session state: %s", state.toString()));
                if (state == SessionState.OPENED)
                {
                    mDataSet.setUserID(null);
                    Request request = Request.newMeRequest(session, new Request.GraphUserCallback() {
                        @Override
                        public void onCompleted(GraphUser user, Response response) {

                            // If the response is successful
                            if (session == Session.getActiveSession()) {
                                if (user != null) {
                                    mDataSet.setUserID(user.getId());
                                    Log.d("LoginFacebookFragment", "UserID: " + mDataSet.getUserID());

                                    if (mDataSet.getUserID() != null)
                                    {
                                        int i = mDataSet.getMenuPosition();

                                        if (i == 1 || i == 2)
                                        {
                                            Fragment fragment = new OccurenceReportFragment();
                                            FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();

                                            ft.replace(R.id.content_frame, fragment);
                                            ft.addToBackStack(null);
                                            ft.commit();
                                        }
                                    }
                                }   
                            }   
                        }
                    }); 
                    Request.executeBatchAsync(request);
                }
            }
        });
        return rootView;
    }

    @Override
    public void onDestroyView() {
        UserSettingsFragment f = (UserSettingsFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.login_fragment);
        if (f != null) {
            try {
                getActivity().getSupportFragmentManager().beginTransaction().remove(f).commit();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        super.onDestroyView();
    }

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

Here is my fragment layout containing the UserSettingsFragment:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <fragment
        android:id="@+id/login_fragment"
        android:name="com.facebook.widget.UserSettingsFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

The error log:

04-30 19:18:56.848: W/dalvikvm(7814): threadid=1: thread exiting with uncaught exception (group=0x41d247c0)
04-30 19:18:56.871: E/AndroidRuntime(7814): FATAL EXCEPTION: main
04-30 19:18:56.871: E/AndroidRuntime(7814): java.lang.IllegalStateException: Fragment UserSettingsFragment{424205c8} not attached to Activity
04-30 19:18:56.871: E/AndroidRuntime(7814):     at android.support.v4.app.Fragment.getResources(Fragment.java:601)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at com.facebook.widget.UserSettingsFragment.processImageResponse(UserSettingsFragment.java:441)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at com.facebook.widget.UserSettingsFragment.access$7(UserSettingsFragment.java:437)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at com.facebook.widget.UserSettingsFragment$2.onCompleted(UserSettingsFragment.java:428)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at com.facebook.internal.ImageDownloader$1.run(ImageDownloader.java:168)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at android.os.Handler.handleCallback(Handler.java:730)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at android.os.Handler.dispatchMessage(Handler.java:92)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at android.os.Looper.loop(Looper.java:137)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at android.app.ActivityThread.main(ActivityThread.java:5289)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at java.lang.reflect.Method.invokeNative(Native Method)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at java.lang.reflect.Method.invoke(Method.java:525)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
04-30 19:18:56.871: E/AndroidRuntime(7814):     at dalvik.system.NativeStart.main(Native Method)
04-30 19:18:56.902: I/Process(7814): Sending signal. PID: 7814 SIG: 9

What am I doing wrong? Is there any way to solve that? Please help me, it's an important project!

Thanks!

Was it helpful?

Solution

Its late night and I'm too sleepy to read your code clearly!! But I see something in your code that may cause the problem. You are adding your fragment inside xml file and by doing so you can not replace it. If you want to be able to dynamically remove or replace a fragment you should add it using java code.

I hope this will help.

OTHER TIPS

I got it! Instead of using a own Fragment which adds the UserSettingsFragment, I directly add the UserSettingsFragment after setting my own SessionStatusCallback to it.

...
UserSettingsFragment fmt = new UserSettingsFragment();
fmt.setSessionStatusCallback(new MyFBSessionStatusCallback(getActivity()));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fmt);
ft.addToBackStack(null);
ft.commit();
...

My SessionStatusCallback class:

public class MyFBSessionStatusCallback implements Session.StatusCallback {

    private DataSet mDataSet;
    private FragmentActivity mFragAct;

    public MyFBSessionStatusCallback (FragmentActivity fragment) {
        this.mFragAct = fragment;
        this.mDataSet = DataSet.getInstance();
    }

    @Override
    public void call(final Session session, SessionState state, Exception exception) {
        Log.d("LoginFacebookFragment", String.format("New session state: %s", state.toString()));
        if (state == SessionState.OPENED)
        {
            mDataSet.setUserID(null);
            Request request = Request.newMeRequest(session, new Request.GraphUserCallback() {
                @Override
                public void onCompleted(GraphUser user, Response response) {

                    // If the response is successful
                    if (session == Session.getActiveSession()) {
                        if (user != null) {
                            mDataSet.setUserID(user.getId());
                            Log.d("LoginFacebookFragment", "UserID: " + mDataSet.getUserID());
                            ...
                        }   
                    }   
                }
            }); 
            Request.executeBatchAsync(request);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top