Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

facebook login Cannot pass a publish or manage permission (email) to a request for read authorization

I have a button click to login facebook,but sometimes this code can't work. throw exception:Caused by:

com.facebook.FacebookException: Cannot pass a publish or manage permission (email) to a request for read authorization

This is my activity's code :

public class FacebookLoginActivity extends Activity {

    private final static String TAG="FB";

    private static final List<String> PERMISSIONS=Arrays.asList("email", "user_likes", "user_status");

    private Session.StatusCallback statusCallback=new SessionStatusCallback();

    private GraphUser user = null;

    private Bundle bundle;

    private Intent myIntent;

    private Session session;

    private static FacebookLoginActivity instance=new FacebookLoginActivity();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(bundle==null){
            bundle=new Bundle();
        }
        Log.v(TAG, "in FB onCreate method");
        myIntent = this.getIntent();
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        String action = ClientUtil.getElementValue("action");

        Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
        session=openActiveSession(this, true, PERMISSIONS);
        onClickLogin();
    }



    public void onClickLogin() {
        Log.v(TAG, "click login btn");
        session = Session.getActiveSession();
        if (!session.isOpened() && !session.isClosed()) {
            OpenRequest openRequest=new Session.OpenRequest(this);
            openRequest.setPermissions(PERMISSIONS);
            openRequest.setCallback(statusCallback);
            openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS);
            openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
            session.openForPublish(openRequest);
        } else {
            Log.v(TAG, "open active session");
            Session.openActiveSession(this, true, statusCallback);
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.v(TAG, "onStart method to add  fb Callback");
        Session.getActiveSession().addCallback(statusCallback);
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.v(TAG, "onStop method to remove fb callback");
        Session.getActiveSession().removeCallback(statusCallback);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.v(TAG, "onActivityResult method to call Fb Session");
        Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Session session=Session.getActiveSession();
        Session.saveSession(session, outState);
    }

    private static Session openActiveSession(Activity activity, boolean allowLoginUI, List<String> permissions) {
        OpenRequest openRequest = new OpenRequest(activity).setPermissions(permissions);
        Session session = new Session.Builder(activity).build();
        if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) {
            Session.setActiveSession(session);
            session.openForPublish(openRequest);
            return session;
        }
        return null;
    }

    private class SessionStatusCallback implements Session.StatusCallback {

        @Override
        public void call(Session session, SessionState state, Exception exception) {
            Log.v(TAG, "in StatusCallback call method exception is:"+ exception);
            Log.v(TAG, "session state is:"+session.isOpened());
            if(user != null) {
                Log.v(TAG, "fb user is exist todo login yyy");
                login();
                finish();
                Log.v(TAG, "finish fb activity");
                return;
            }
            if(session.isOpened()) {
                Log.v(TAG, "session is opened to call FB Request");
                Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {

                    @Override
                    public void onCompleted(GraphUser me, Response response) {
                        Log.v(TAG, "in GraphUserCallback onCompleted method");
                        Log.v(TAG, "GraphUser has value:"+(user!=null));
                        if(me != null) {
                            user=me;
                            login();
                        }
                        finish();
                        Log.v(TAG, "finish fb activity");
                    }
                });
            }else{
                Log.v(TAG, "session is not open");
                if(exception !=null && exception.toString().contains("Canceled")){
                    Log.v(TAG, "cancle login");
                    bundle.putInt("code", RespondCode.CANCLE);
                    myIntent.putExtras(bundle);
                    setResult(Activity.RESULT_OK, myIntent);
                    finish();
                }
            }
        }
    }       
}
like image 452
user2122690 Avatar asked Mar 01 '13 08:03

user2122690


2 Answers

You can't call openForPublish unless your app has already been granted basic permissions first.

Separate out your PERMISSIONS list into PERMISSIONS_READ and PERMISSIONS_PUBLISH, and put "email" into the PUBLISH side. Then call openForRead, and then requestNewPublishPermissions when your session is open.

like image 191
Ming Li Avatar answered Oct 06 '22 01:10

Ming Li


Here is the thing you should do, it helped me in getting my requirement done:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mLogin = (Button) findViewById(R.id.logIn);
    mLogin.setOnClickListener(this);

}

@Override
public void onClick(View v) {

    Session currentSession = Session.getActiveSession();
    if (currentSession == null || currentSession.getState().isClosed()) {
        Session session = new Session.Builder(context).build();
        Session.setActiveSession(session);
        currentSession = session;
    }

    if (currentSession.isOpened()) {
        // Do whatever u want. User has logged in

    } else if (!currentSession.isOpened()) {
        // Ask for username and password
        OpenRequest op = new Session.OpenRequest((Activity) context);

        op.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
        op.setCallback(null);

        List<String> permissions = new ArrayList<String>();
        permissions.add("publish_stream");
        permissions.add("user_likes");
        permissions.add("email");
        permissions.add("user_birthday");
        op.setPermissions(permissions);

        Session session = new Builder(MainActivity.this).build();
        Session.setActiveSession(session);
        session.openForPublish(op);
    }
}

public void call(Session session, SessionState state, Exception exception) {
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (Session.getActiveSession() != null)
        Session.getActiveSession().onActivityResult(this, requestCode,
                resultCode, data);

    Session currentSession = Session.getActiveSession();
    if (currentSession == null || currentSession.getState().isClosed()) {
        Session session = new Session.Builder(context).build();
        Session.setActiveSession(session);
        currentSession = session;
    }

    if (currentSession.isOpened()) {
        Session.openActiveSession(this, true, new Session.StatusCallback() {

            @Override
            public void call(final Session session, SessionState state,
                    Exception exception) {

                if (session.isOpened()) {

                    Request.executeMeRequestAsync(session,
                            new Request.GraphUserCallback() {

                                @Override
                                public void onCompleted(GraphUser user,
                                        Response response) {
                                    if (user != null) {

                                        TextView welcome = (TextView) findViewById(R.id.welcome);
                                        welcome.setText("Hello "
                                                + user.getName() + "!");

                                        access_token = session
                                                .getAccessToken();
                                        firstName = user.getFirstName();
                                        fb_user_id = user.getId();

                                        System.out
                                                .println("Facebook Access token: "
                                                        + access_token);
                                        System.out.println("First Name:"
                                                + firstName);
                                        System.out.println("FB USER ID: "
                                                + fb_user_id);

                                    }
                                }
                            });
                }
            }
        });
    }
}

Try the above code, it is just what you wanted to have.

like image 23
Anupam Avatar answered Oct 05 '22 23:10

Anupam