java - Android 集成的 Facebook 无法始终如一地工作

标签 java android facebook race-condition facebook-android-sdk

我正在尝试将 Facebook 登录与我的应用集成。很简单:用户在我的登录屏幕上单击一个按钮,我从 Facebook 获取他们的电子邮件和其他信息,然后我将该信息提交到我的网站并为他们创建一个帐户(我不使用密码,所以这有效)。

但是,登录按钮只有 1/3 的时间有效。其他时候它启动 Facebook Activity ,我在 Facebook 屏幕上看到一个加载微调器,然后应用程序退出到我的主屏幕。没有强制关闭通知,没有 logcat 错误,什么都没有。

这是我登录 Activity 的代码(与 Facebook 相关的部分):

package com.taptag.beta;

/** IMPORTS REMOVED FOR BREVITY **/

public class FacebookLogInActivity extends NetworkActivity {
    public static final String APP_ID = "OMITTED FOR PRIVACY";
    public static final String LOG_OUT = "Log Out";

    Facebook facebook = new Facebook(APP_ID);

    private AsyncFacebookRunner mAsyncRunner;
    private Handler mHandler;
    private SharedPreferences mPrefs;
    private Button mLoginButton;
    private static final String[] PERMISSIONS = { "email" };

    private EditText firstName;
    private EditText lastName;
    private EditText email;
    private Button signupButton;

    private TextView errorView;
    private ProgressBar facebookSpinner;
    private ProgressBar signupSpinner;

    //Taken from mkyong
    private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    private Pattern emailPattern;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.facebook_main);

        mPrefs = getSharedPreferences("TapTag", MODE_PRIVATE);
        Integer userId = mPrefs.getInt("user_id", -1);

        mLoginButton = (Button) findViewById(R.id.loginButton);

        // Facebook properties
        mAsyncRunner = new AsyncFacebookRunner(facebook);
        mHandler = new Handler();
        // Get existing saved session information
        String access_token = mPrefs.getString("access_token", null);
        long expires = mPrefs.getLong("access_expires", 0);

        if (access_token != null) {
            facebook.setAccessToken(access_token);
        }
        if (expires != 0) {
            facebook.setAccessExpires(expires);
        }

        errorView = (TextView) findViewById(R.id.signupError);
        facebookSpinner = (ProgressBar) findViewById(R.id.facebookSpinner);
        signupSpinner = (ProgressBar) findViewById(R.id.signupSpinner);

        hideSpinners();
        errorView.setVisibility(View.GONE);

        emailPattern = Pattern.compile(EMAIL_PATTERN);
        firstName = (EditText) findViewById(R.id.signupFirstName);
        lastName = (EditText) findViewById(R.id.signupLastName);
        email = (EditText) findViewById(R.id.signupEmail);
        signupButton = (Button) findViewById(R.id.signupButton);

        signupButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isValid = validateInputs();
                if (isValid) {
                    SignupTask signupTask = new SignupTask();
                    signupTask.execute(null, null);
                }
            }
        });

        mLoginButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!facebook.isSessionValid()) {
                    logIn();
                } else {
                    logOut();
                }
            }
        });
    }

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

    @Override
    public void onResume() {
        super.onResume();
        // Extend the session information if it is needed
        //if (facebook != null && !facebook.isSessionValid()) {
            facebook.extendAccessTokenIfNeeded(this, null);
        //}
        if (LOG_OUT.equals(getIntent().getAction())) {
            logOut();
        } else  {
            Integer userId = mPrefs.getInt("user_id", -1);
            if (userId > 0) {
                continueToHomeScreen();
            }
        }
    }

    @Override
    public void onBackPressed() {
        //Do nothing, don't want people getting back into the app
    }

    /**
     * Validate the signup form.  True if valid, false otherwise.
     * @return
     */
    public boolean validateInputs() {
        /** NOT RELEVANT **/
    }

    private FacebookUserInfo userFromForm() {
        /** NOT RELEVANT **/
    }

    private boolean validateFirstName() {
        /** NOT RELEVANT **/
    }

    private boolean validateLastName() {
        /** NOT RELEVANT **/
    }

    private boolean validateEmail() {
        /** NOT RELEVANT **/
    }

    public void hideSpinners() {
        facebookSpinner.setVisibility(View.GONE);
        signupSpinner.setVisibility(View.GONE);
    }

    public void continueToHomeScreen() {
        Intent toHomeScreen = new Intent(FacebookLogInActivity.this, HomeScreenActivity.class);
        FacebookLogInActivity.this.startActivity(toHomeScreen);
    }

    public void logIn() {
        facebookSpinner.setVisibility(View.VISIBLE);
        mLoginButton.setVisibility(View.GONE);
        facebook.authorize(FacebookLogInActivity.this, PERMISSIONS, new DialogListener() {
            @Override
            public void onComplete(Bundle values) {
                SharedPreferences.Editor editor = mPrefs.edit();
                editor.putString("access_token", facebook.getAccessToken());
                editor.putLong("access_expires", facebook.getAccessExpires());
                editor.commit();
                requestUserData();
            }

            @Override
            public void onFacebookError(FacebookError e) {
                mLoginButton.setVisibility(View.VISIBLE);
                hideSpinners();

            }
            @Override
            public void onError(DialogError e) {
                mLoginButton.setVisibility(View.VISIBLE);
                hideSpinners();
            }
            @Override
            public void onCancel() {
                mLoginButton.setVisibility(View.VISIBLE);
                hideSpinners();
            }
        });
    }

    public void logOut() {
        /** NOT RELEVANT **/
    }

    public void requestUserData() {
        Bundle params = new Bundle();
        params.putString("field name", "name");
        params.putString("field email", "email");

        mAsyncRunner.request("me", params, new BaseRequestListener() {
            @Override
            public void onComplete(final String response, final Object state) {
                FacebookUserInfo facebookUserInfo = TapTagAPI.userInfoFromFacebook(response);
                UserFetchResponse userFetchResponse = TapTagAPI.fetchUser(facebookUserInfo);
                if (!userFetchResponse.hasError()) {
                    commitUserInfo(userFetchResponse);
                    continueToHomeScreen();
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            hideSpinners();
                            mLoginButton.setVisibility(View.VISIBLE);
                        }
                    });
                }
            }
        });
    }

    public void commitUserInfo(UserFetchResponse userFetchResponse) {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putInt("user_id", userFetchResponse.getId());
        editor.putString("user_name", userFetchResponse.getFirst() + " " + userFetchResponse.getLast());
        editor.commit();
    }

    public class SignupTask extends AsyncTask<Void, Void, UserFetchResponse> {
        @Override
        protected void onPreExecute() {
            signupSpinner.setVisibility(View.VISIBLE);
            signupButton.setVisibility(View.GONE);
        }

        @Override
        protected UserFetchResponse doInBackground(Void... arg0) {
            FacebookUserInfo user = userFromForm();
            UserFetchResponse response = TapTagAPI.fetchUser(user);
            return response;
        }

        @Override
        protected void onPostExecute(UserFetchResponse response) {
            if (response.success()) {
                commitUserInfo(response);
                continueToHomeScreen();
            } else {
                errorView.setVisibility(View.VISIBLE);
            }
        }
    }

}

最佳答案

在下面写登录函数而不是你的登录函数,它会解决你的问题。

public void logIn() {
    facebookSpinner.setVisibility(View.VISIBLE);
    mLoginButton.setVisibility(View.GONE);
    facebook.authorize(FacebookLogInActivity.this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH, new DialogListener() {
        @Override
        public void onComplete(Bundle values) {
            SharedPreferences.Editor editor = mPrefs.edit();
            editor.putString("access_token", facebook.getAccessToken());
            editor.putLong("access_expires", facebook.getAccessExpires());
            editor.commit();
            requestUserData();
        }

        @Override
        public void onFacebookError(FacebookError e) {
            mLoginButton.setVisibility(View.VISIBLE);
            hideSpinners();
        }

        @Override
        public void onError(DialogError e) {
            mLoginButton.setVisibility(View.VISIBLE);
            hideSpinners();
        }

        @Override
        public void onCancel() {
            mLoginButton.setVisibility(View.VISIBLE);
            hideSpinners();
        }
    });
}

关于java - Android 集成的 Facebook 无法始终如一地工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12119546/

相关文章:

java - 更新端点的响应对象

java - 如何让这个简单的笔记应用程序正常工作?

android - 使用 Volley Android 库发送 XML 数据

android - 如何获取 dataclient.getDataItem(Uri) 自己的 node_id?

facebook - Facebook 调试器中 'og:type' 的值错误

android - 一旦我们通过 Android 应用程序登录,如何显示 facebook 个人资料的新闻提要?

php - Facebook 营销 API - 添加 ProductCatalog

java - 如何缩短类似按钮的 findViewById 和 setOnClickListener ?

java - 如何正确地将 Java 中的 double 值设置为两位数

java - 为 Android Studio 启用硬件加速