#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 не могли бы вы опубликовать код, пожалуйста — у меня такая же проблема