Android facebook - 用户在权限对话框中取消后,为什么权限“消失”?

时间:2014-03-09 05:49:22

标签: android facebook session permissions

工作流程如下:

用户点击登录 - >登录成功后 - >提示权限对话框,如果接受,登录,如果取消,下次再次打开该框

问题是,权限对话框第一次请求了电子邮件权限,但是,如果用户单击取消并稍后打开该框,则电子邮件权限似乎不再存在,它只是询问用户的个人信息。

如何解决这个问题?感谢

更新:我尝试修复代码,但是,它会抛出异常,它似乎与流逻辑有关。如何解决这个问题?我将提供我的代码的详细信息,感谢您的帮助。

修改:

  1. 添加了private final static List<String> PERMISSIONS = Arrays.asList("email");

  2. 更新onclickLogin()

    private void onClickLogin() {
    Session session = Session.getActiveSession();
    List<String> permissions = session.getPermissions();
    
    Log.d("test1","p:" + permissions);
    Log.d("test1","session open" + session.isOpened());
    
    if (!session.isOpened() && !session.isClosed()) {
        Log.d("test1","test1");
        session.openForRead(new Session.OpenRequest(this).setPermissions("email").setCallback(statusCallback));
    } else if(!isSubset(PERMISSIONS, permissions)) {
        Log.d("test1","test2");
        Session.NewPermissionsRequest newPermissions = new Session.NewPermissionsRequest(this, PERMISSIONS);
        session.requestNewPublishPermissions(newPermissions); 
    } else {
        Log.d("test1","test3");
        Session.openActiveSession(getActivity(), this, true, statusCallback);
    }
    

    }

  3. 添加了isSubset()

  4. 日志cat输出

    03-09 14:30:29.301: D/test1(23828): p:[]
    03-09 14:30:29.301: D/test1(23828): session openfalse
    03-09 14:30:29.301: D/test1(23828): test1
    03-09 14:30:42.654: D/test1(23828): p:[]
    03-09 14:30:42.654: D/test1(23828): session openfalse
    03-09 14:30:42.654: D/test1(23828): test2
    

    例外

    03-09 14:30:42.694: E/AndroidRuntime(23828): java.lang.UnsupportedOperationException: Session: an attempt was made to request new permissions for a session that has been closed.
    

    注意:在点击取消并第二次打开该框后,似乎仍未打开会话,因此我删除了Session.isopened检查。否则它只会落入第三个条件

    以下是Class的完整代码:

    public class Home extends Fragment implements LoginListener {
        private final static String TAG = "Home";
        public View rootView;
        public ImageView HomeBg;
        public ImageView buttonLoginLogout;
        public TextView chi;
        public TextView eng;
        public ColorStateList oldColor;
        public SharedPreferences prefs;
        public EasyTracker tracker = null;
        public SharedPreferences.Editor editor;
        public ProgressDialog pd;
        public Home ctx;
    
        //Facebook login
        private Session.StatusCallback statusCallback = new SessionStatusCallback();
        private final static List<String> PERMISSIONS = Arrays.asList("email");
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState); 
            ctx = this;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    
            try{
                // fix for disable the hiding action bar animation
                getActivity().getActionBar().getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class).invoke(getActivity().getActionBar(), false);
            } catch (Exception exception){
                // animation will be run if not support
            }
    
            getActivity().getActionBar().hide();
    
            tracker = EasyTracker.getInstance(getActivity());
    
            prefs = getActivity().getSharedPreferences("userInfo", 0);
            editor = prefs.edit();
    
            rootView = inflater.inflate(R.layout.home, container, false);
            buttonLoginLogout = (ImageView) rootView.findViewById(R.id.home_connectFB);
            eng = (TextView) rootView.findViewById(R.id.btn_eng);
            chi = (TextView) rootView.findViewById(R.id.btn_chi);
    
            eng.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View arg0) {
                    if (!Utility.getLocale(getActivity()).equals("en")) {
                        tracker.send(MapBuilder.createEvent("menu_click","language", "switchEN", null).build());
                        chi.setTextColor(oldColor);
                        eng.setTextColor(getActivity().getResources().getColor(android.R.color.white));
                        MyApp.updateLanguage(getActivity().getApplicationContext(), "en");
                        refreshAfterLocaleChanged("en");
                    }
                }
            });
    
            chi.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View arg0) {
                    if (!Utility.getLocale(getActivity()).equals("zh")) {
                        tracker.send(MapBuilder.createEvent("menu_click","language", "switchTC", null).build());
                        eng.setTextColor(oldColor);
                        chi.setTextColor(getActivity().getResources().getColor(android.R.color.white));
                        MyApp.updateLanguage(getActivity().getApplicationContext(), "zh");
                        refreshAfterLocaleChanged("zh");
                    }
                }
            });
    
            if (Utility.getLocale(getActivity()).equals("zh")) {
                chi.setTextColor(getActivity().getResources().getColor(
                        android.R.color.white));
                oldColor = eng.getTextColors();
            } else {
                eng.setTextColor(getActivity().getResources().getColor(
                        android.R.color.white));
                oldColor = chi.getTextColors();
    
            }
    
            //Facebook login
            Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
    
            Session session = Session.getActiveSession();
            if (session == null) {
                if (savedInstanceState != null) {
                    session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState);
                }
                if (session == null) {
                    session = new Session(getActivity());
                }
                Session.setActiveSession(session);
                if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
                   // session.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("basic_info","email")).setCallback(statusCallback));
                    session.openForRead(new Session.OpenRequest(this).setPermissions("email").setCallback(statusCallback));
                }
            }
    
           updateView();
    
           return rootView;
        }
    
        public void refreshAfterLocaleChanged(String lang){
            SharedPreferences langPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
            Editor editor = langPrefs.edit();
            editor.putString("lang",lang).commit();
    
            Intent intent = getActivity().getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            getActivity().finish();
            getActivity().overridePendingTransition(0, 0);
            startActivity(intent);
        }
    
        @Override
        public void onStart() {
            super.onStart();
            Session.getActiveSession().addCallback(statusCallback);
            tracker.set(Fields.SCREEN_NAME, "hk7app/CX/" + Utility.getLocale(getActivity()) + "/Landing Page");
            tracker.send(MapBuilder.createAppView().build());
        }
    
        @Override
        public void onStop() {
            super.onStop();
    
            if (pd != null)
                pd.dismiss();
    
            Session.getActiveSession().removeCallback(statusCallback);
            EasyTracker.getInstance(getActivity()).activityStop(getActivity());
        }
    
        @SuppressWarnings("deprecation")
        private void updateView() {
            Session session = Session.getActiveSession();
            if (session.isOpened()) {
                 final String token = session.getAccessToken();
                 Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
                        @Override
                        public void onCompleted(GraphUser user,Response response) {
                            // TODO Auto-generated method stub
                            if (user != null) {
                                if (!user.getId().equals(prefs.getString("fbId",""))) {
                                    editor.putString("fbId", user.getId());
                                    editor.putString("fName", user.getFirstName());
                                    editor.putString("lName", user.getLastName());
                                    if (user.asMap() != null && user.asMap().get("email") != null) {
                                        editor.putString("email", user.asMap().get("email").toString());
                                    }
                                    editor.commit();
                                }
                                if (prefs.getString("memId","").equals("") || prefs.getString("token","").equals("") || !user.getId().equals(prefs.getString("fbId",""))){
                                    pd = ProgressDialog.show(getActivity(), getActivity().getResources().getString(R.string.sys_info),getActivity().getResources().getString(R.string.loading));
                                    new APIHandler(getActivity(),tracker,"login",pd).execute(ctx,token);
                                } else {
                                    onLoginComplete("","");
                                }
                            }
                        }
                 });                  
            } else {
                buttonLoginLogout.setImageResource(R.drawable.landing_btn_connect_facebook);
                buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View view) { onClickLogin(); }
                });
            }
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            Session session = Session.getActiveSession();
            Session.saveSession(session, outState);
        }
    
        private void onClickLogin() {
            tracker.send(MapBuilder.createEvent("menu_click","Fbconnect","connectFB_" + Utility.getLocale(getActivity()),null).build());
            Session session = Session.getActiveSession();
            List<String> permissions = session.getPermissions();// to get the session permissions
    
            Log.d("test1","p:" + permissions);
            Log.d("test1","session open" + session.isOpened());
    
            if (!session.isOpened() && !session.isClosed()) {
                Log.d("test1","test1");
                session.openForRead(new Session.OpenRequest(this).setPermissions("email").setCallback(statusCallback));
            } else if(!isSubset(PERMISSIONS, permissions)) {
                Log.d("test1","test2");
                Session.NewPermissionsRequest newPermissions = new Session.NewPermissionsRequest(this, PERMISSIONS);
                session.requestNewPublishPermissions(newPermissions); 
            } else {
                Log.d("test1","test3");
                Session.openActiveSession(getActivity(), this, true, statusCallback);
            }
        }
    
        //this function is to check if the user has a specific permission within the session
        private boolean isSubset(Collection<String> subset, Collection<String> superset) {
            for (String string : subset) {
                if(!superset.contains(string))
                    return false;
            }
            return true;
        }
    
        private class SessionStatusCallback implements Session.StatusCallback {
            @Override
            public void call(Session session, SessionState state, Exception exception) {
                Log.d(TAG,"SessionStatusCallback");
                if (exception != null) {
                    Log.d(TAG,""+exception);
    
                    if (!session.isClosed()) {
                       session.closeAndClearTokenInformation(); //reset session
                       Session.setActiveSession(null);
                    }
    
                    if (exception instanceof FacebookAuthorizationException){
                        new AlertDialog.Builder(getActivity())
                        .setTitle(ctx.getResources().getString(R.string.sys_info))
                        .setMessage(R.string.facebook_permission_missing)
                        .setPositiveButton(ctx.getResources().getString(R.string.close), null)
                        .show();
                    }
                } else {
                    updateView();
                }
            }
        }
    
        @Override
        public void onResume() {
            super.onResume();
            AppEventsLogger.activateApp(getActivity(),getResources().getString(R.string.app_id));
        }
    
        @Override
        public void onLoginComplete(String memberId, String token) {    
            if (pd != null)
                pd.dismiss();
    
            if (!memberId.equals("") && !token.equals("")) {
                editor.putString("memId", memberId);
                editor.putString("token", token);
                editor.commit();
            }
    
            buttonLoginLogout.setImageResource(R.drawable.landing_btn_take_a_selfie);
            buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                     tracker.send(MapBuilder.createEvent("menu_click","TakeSelfie","Selfie_now_" + Utility.getLocale(getActivity()),null).build());
                    ((LandingPage)getActivity()).tabHost.setCurrentTab(2);
                }
            });
        }
    
        @Override
        public void onLoginFailure(String errorMsg) {
            if (pd != null)
                pd.dismiss();
    
            Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show();
        }
    
    }
    

2 个答案:

答案 0 :(得分:1)

当然因为会话已经存在...所以会调用else ..你需要检查活动会话中是否存在权限..

添加以下内容:..

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

然后在'onClickLogin'中添加if-else语句块..

List<String> permissions = session.getPermissions();// to get the session permissions
else if(session.isOpened() && !isSubset(PERMISSIONS, permissions) {
   Session.NewPermissionsRequest newPermissions = new Session.NewPermissionsRequest(this, PERMISSIONS);
   session.requestNewPublishPermissions(newPermissions); 
}

isSubset函数

//this function is to check if the user has a specific permission within the session
private boolean isSubset(Collection<String> subset, Collection<String> superset) {
    for (String string : subset) {
        if(!superset.contains(string))
            return false;
    }
    return true;
}

这是关于每次用户访问活动时如何显示消息的一般概念(如果您使用的是uiLifeCycleHelper),因此您仍需要对其进行更多修改以满足您的需求。

答案 1 :(得分:0)

当用户第一次按下权限上的取消按钮时,会话永远不会打开,会话也不会正常关闭。它会返回“CLOSED_LOGIN_FAILED”作为会话状态字段的值。您可以通过以下方式检查: session.getState()的toString(); 这就是为什么你的其他if块因某种原因无效的原因。 其次,当我执行newPermission语句时,它给了我一个错误,显然在设置权限之前需要打开会话。

所以,以下内容对我有用: 在onClickLogin()中,将以下代码添加到else if if:

    else if(session.getState().toString().equals("CLOSED_LOGIN_FAILED") && !isSubset(PERMISSIONS, permissions)){
      Log.v("LoginType","Login+PermissionsforCancelledTimes");

      Session.openActiveSession( Login.this, true, Arrays.asList("public_profile","email") ,statusCallback);
}