Как я могу правильно получить токен доступа и другую информацию после входа в приложение Facebook и авторизации моего приложения? [Android]

#java #android #facebook #login

#java #Android #Facebook #аутентификация

Вопрос:

Я использую это. В моем Facebook.java в моем authorized() методе я вызываю startSingleSignOn и startDialogAuth , я использую DEFAULT_AUTH_ACTIVITY_CODE вместо FORCE_DIALOG_AUTH

public void авторизует (Activity activity, разрешения String[], int activityCode, конечный прослушиватель DialogListener) {

     boolean singleSignOnStarted = false;

    mAuthDialogListener = listener;

    // Prefer single sign-on, where available.
    if (activityCode >= 0) {
        singleSignOnStarted = startSingleSignOn(activity, mAppId,
                permissions, activityCode);
    }
    // Otherwise fall back to traditional dialog.
    if (!singleSignOnStarted) {
        startDialogAuth(activity, permissions);
    }
}
  

Я заметил, что в моем startDialogAuth ит устанавливается AccessToken и AccessExpires

 private void startDialogAuth(Activity activity, String[] permissions) {

    Bundle params = new Bundle();
    if (permissions.length > 0) {
        params.putString("scope", TextUtils.join(",", permissions));
    }
    CookieSyncManager.createInstance(activity);
    dialog(activity, LOGIN, params, new DialogListener() {

        public void onComplete(Bundle values) {

            // ensure any cookies set by the dialog are saved
            CookieSyncManager.getInstance().sync();
            setAccessToken(values.getString(TOKEN));
            setAccessExpiresIn(values.getString(EXPIRES));
            if (isSessionValid()) {
                Util.logd("Facebook-authorize", "Login Success! access_token="
                          getAccessToken()   " expires="
                          getAccessExpires());

                mAuthDialogListener.onComplete(values);
            } else {
                mAuthDialogListener.onFacebookError(new FacebookError(
                                "Failed to receive access token."));
            }
        }

        public void onError(DialogError error) {
            Util.logd("Facebook-authorize", "Login failed: "   error);
            mAuthDialogListener.onError(error);
        }

        public void onFacebookError(FacebookError error) {
            Util.logd("Facebook-authorize", "Login failed: "   error);
            mAuthDialogListener.onFacebookError(error);
        }

        public void onCancel() {
            Util.logd("Facebook-authorize", "Login canceled");
            mAuthDialogListener.onCancel();
        }
    });
}
  

И в startSingleSignOn нем это выглядит так

 private boolean startSingleSignOn(Activity activity, String applicationId,
        String[] permissions, int activityCode) {
    boolean didSucceed = true;
    Intent intent = new Intent();

    intent.setClassName("com.facebook.katana",
            "com.facebook.katana.ProxyAuth");
    intent.putExtra("client_id", applicationId);

    if (permissions.length > 0) {
        intent.putExtra("scope", TextUtils.join(",", permissions));
    }

    // Verify that the application whose package name is
    // com.facebook.katana.ProxyAuth
    // has the expected FB app signature.
    if (!validateActivityIntent(activity, intent)) {
        return false;
    }

    mAuthActivity = activity;
    mAuthPermissions = permissions;
    mAuthActivityCode = activityCode;

    try {
        activity.startActivityForResult(intent, activityCode);
    } catch (ActivityNotFoundException e) {
        didSucceed = false;
    }

    return didSucceed;
}
  

Мне интересно, где он устанавливает Access Token то, что необходимо при входе в систему, я сталкиваюсь с проблемой, когда пользователь Facebook app установил и уже авторизовал мое приложение, оно покажет только диалоговое окно (загрузка) и отобразит белый экран, а затем отклонит, но дальше ничего не произойдет. Он не получает информацию пользователя из зарегистрированного Facebook app . Но когда у пользователя нет Facebook app , он отображает WebView и просто работает нормально, он входит в систему правильно. Во время отладки я также замечаю, что он не входит в мою функцию LoginDialogListener , которую он реализует Facebook.DialogListener (когда установлено приложение facebook), возможно, потому, что в startSingleSignOn нем не вызывается CookieSyncManager.createInstance(activity);
dialog(activity, LOGIN, params, new DialogListener() {

вот мой activity код, в котором он вызывает facebook.authorize

 public void setFacebookConnection() {
    facebook = new Facebook(Constants.FACEBOOK_APP_ID);
    facebookAsyncRunner = new AsyncFacebookRunner(facebook);

    facebook.authorize(this, Constants.FACEBOOK_PERMISSIONS, new LoginDialogListener());
}

private class LoginDialogListener implements Facebook.DialogListener {
    public void onComplete(Bundle values) {
        Log.d(TAG, "LoginONComplete");
        String token = facebook.getAccessToken();
        long token_expires = facebook.getAccessExpires();
        Log.d(TAG, "AccessToken: "   token);
        Log.d(TAG, "AccessExpires: "   token_expires);

        if (isPublishStreamAuthorized()) {
            facebookSharedPreferences = PreferenceManager
                    .getDefaultSharedPreferences(context);
            facebookSharedPreferences
                    .edit()
                    .putLong(Constants.FACEBOOK_ACCESS_EXPIRES,
                            token_expires).commit();
            facebookSharedPreferences.edit()
                    .putString(Constants.FACEBOOK_ACCESS_TOKEN, token)
                    .commit();
            facebookAsyncRunner.request("me", new IDRequestListener());
        } else {
            logoutFacebook();
        }

    }

    public void onFacebookError(FacebookError e) {
        Log.d(TAG, "FacebookError: "   e.getMessage());
    }

    public void onError(DialogError e) {
        Log.d(TAG, "Error: "   e.getMessage());
        Toast.makeText(getApplicationContext(), Constants.NO_INTERNET_CONNECTION,
                Toast.LENGTH_LONG).show();
    }

    public void onCancel() {
        Log.d(TAG, "OnCancel");
        logoutFacebook();
    }

}
  

Кажется, что my facebook.getAccessToken(); in my activity возвращает null, так как пытался вызвать my setFacebookConnection() после вызова facebook.authorize()

Не могли бы вы мне помочь? Мне нужно было решить это в ближайшее время. Большое вам спасибо.

Обновить

Я нашел это и попытался выполнить шаг 3, но в итоге WebView он снова открывается.

*** Обновить

Я, наконец, получаю access token , позвонив onActivityResult() , но данные get будут отображаться только после того, как я закрою приложение и снова открою его. вот мой код, FACEBOOK_AUTH_RESULT_CODE значение которого я изменил на 32665.

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == Constants.FACEBOOK_AUTH_RESULT_CODE) {
        facebook.authorizeCallback(requestCode, resultCode, data);
    } else {
        Log.e(TAG, "onActivityResult Error : Authentication Error");
    }
} 
  

Комментарии:

1. Код, на который вы ссылаетесь, слишком старый. Некоторые из них могут быть устаревшими. Попробуйте официальные документы и примеры developers.facebook.com/docs/android/getting-started

2. @MahendranSakkarai мне нужно использовать это, чтобы избежать больших изменений: (

Ответ №1:

gradle:

 compile 'com.facebook.android:facebook-android-sdk:[4,5)'
  

strings.xml

 <string name="facebook_app_id">YOUR_APP_ID</string>
  

AndroidManifest.xml
Добавить внутри тега «приложение»:

  <meta-data
        android:name="com.facebook.sdk.ApplicationId"
        android:value="@string/facebook_app_id" />
  

Создайте это для инициализации FacebookSDK:

 public class MainApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FacebookSdk.sdkInitialize(getApplicationContext());
    }
}
  

Добавьте его в AndroidManifest.xml к тегу «приложение» в качестве имени:

 <application
    android:name=".MainApp"
  

В макете вашей активности добавьте кнопку входа в Facebook:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.app.FacebookLoginActivity">

 <com.facebook.login.widget.LoginButton
        android:id="@ id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="30dp" />

</RelativeLayout>
  

Ваша FacebookLoginActivity: и здесь вы можете получить свой токен Facebook.

 public class FacebookLoginActivity extends AppCompatActivity{

private CallbackManager callbackManager;
private LoginButton loginButton;
private String FB_TOKEN;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_signin);
    callbackManager = CallbackManager.Factory.create();
    loginButton = (LoginButton) findViewById(R.id.login_button);
    loginButton.setReadPermissions("public_profile", "user_friends", "email", "user_birthday");
    loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {

            /**
             * HERE YOU CAN GET YOUR FACEBOOK TOKEN!!!!
             **/
            FB_TOKEN=loginResult.getAccessToken().getToken();
        }

        @Override
        public void onCancel() {
        }

        @Override
        public void onError(FacebookException exception) {
        }
    });
}

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

}
  

Если вам нужно использовать пользовательскую кнопку Facebook:

 public class FacebookLoginActivity extends AppCompatActivity{

private CallbackManager callbackManager;
private Button loginButton;
private String FB_TOKEN;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_signin);
    callbackManager = CallbackManager.Factory.create();
    loginButton = (Button) findViewById(R.id.login_button);
    LoginManager.getInstance().registerCallback(callbackManager,
            new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    /**
                    * HERE YOU CAN GET YOUR FACEBOOK TOKEN!!!!
                    **/
                    FB_TOKEN=loginResult.getAccessToken().getToken();
                }

                @Override
                public void onCancel() {
                }

                @Override
                public void onError(FacebookException exception) {
                    Log.e("onError", exception.getMessage());
                }
            });
    loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LoginManager.getInstance().logInWithReadPermissions(FacebookLoginActivity.this, Arrays.asList("public_profile", "user_friends", "email"));
            }
    });
}

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

}
  

Комментарии:

1. Используя приведенный выше код, могу ли я все еще проверить, установлено ли приложение facebook, и если нет, то вместо этого откроется a WebView ?

2. также могу ли я использовать свою пользовательскую кнопку facebook?

3. @mori Да, конечно, я отредактировал свой ответ. Я добавил пример: как использовать пользовательскую кнопку Facebook.

4. @mori спросите меня, если у вас есть какие-либо вопросы =)

5. Большое вам спасибо @Rahim, также как я могу получить token_expires ?

Ответ №2:

1) Вам не нужно использовать тег ‘provider’.

2) com.facebook.FacebookActivity — это собственная активность Facebook, FacebookLoginActivity — ваша.

3) Просто используйте этот код, чтобы получить пол, локаль, подтверждение, адрес электронной почты:

     GraphRequest request = GraphRequest.newMeRequest(
        AccessToken.getCurrentAccessToken(),
        new GraphRequest.GraphJSONObjectCallback() {
            @Override
            public void onCompleted(
                    JSONObject object,
                    GraphResponse response) {
            }
        });
    Bundle parameters = new Bundle();
    parameters.putString("fields", "id,name,gender,verified,locale,email");
    request.setParameters(parameters);
    request.executeAsync();
  

4) Не могли бы вы поделиться своим классом. Мне нужно больше информации о «Неожиданном вызове LoginManager.onActivityResult»

Комментарии:

1. Я исправил Unexpected call to LoginManager.onActivityResult это из-за намерения, которое я вызываю onActivityResult , Большое спасибо за помощь!

2. @natsumiyu не могли бы вы опубликовать код, пожалуйста — у меня такая же проблема