Facebook Android SDK 3.0 renvoie toujours la valeur d'OUVERTURE lors de la connexion
J'ai suivi les instructions à https://developers.facebook.com/docs/howtos/androidsdk/3.0/login-with-facebook/. Quand je touche la "connexion"bouton, l'état de session est en cours d'OUVERTURE - toujours. Quand j'essaie de poster une histoire pour le mur de l'utilisateur je reçois un message d'erreur indiquant
"Session: une tentative a été faite pour demander de nouvelles autorisations pour une session
qui a une demande en attente."
Voici mon code:
public class MainFragment extends Fragment {
private static final String TAG = "MainFragment";
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (state.isOpened()) {
Log.d(TAG, "Logged in...");
} else if (state.isClosed()) {
Log.d(TAG, "Logged out...");
} else {
Log.d(TAG, "Unknown state: " + state);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
//For scenarios where the main activity is launched and user
//session is not null, the session state change notification
//may not be triggered. Trigger it if it's open/closed.
Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed())) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.facebook_login, container, false);
LoginButton authButton = (LoginButton) view
.findViewById(R.id.authButton);
authButton.setFragment(this);
return view;
}
private boolean isSubsetOf(Collection<String> subset,
Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
private static final List<String> PERMISSIONS = Arrays
.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
private boolean pendingPublishReauthorization = false;
public void publishStory() {
Session session = Session.getActiveSession();
if (session != null) {
//Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption",
"Build great social apps and get more installs.");
postParams
.putString(
"description",
"The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link",
"https://developers.facebook.com/android");
postParams
.putString("picture",
"https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback = new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i(TAG, "JSON error " + e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getActivity().getApplicationContext(),
error.getErrorMessage(), Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(getActivity().getApplicationContext(),
postId, Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}
}
Quel est le problème?
Edit: je tiens également à mentionner que le texte sur le "connexion"Bouton ne change pas. Je n'ai pas d'erreur lors de l'authentification, mais autant que j'ai lu il devrait changer de "Log Out".
- Êtes-vous à l'aide de l'authentification unique? Avez-vous le facebook app installé? Êtes-vous passer à travers l'ensemble de l'application d'autorisation de flux de travail? L'erreur que vous voyez suggère que l'application de l'autorisation de flux de travail jamais achevé (et votre fragment de la onActivityResult n'a jamais été appelé), c'est pourquoi la Session pense toujours qu'il y a une demande en attente.
- Oui, je ne l'utilisation de l'authentification unique et j'ai l'application installée. Alors, quand je me connecte à partir de mon application, j'ai l'habitude de ne pas avoir à passer par une autorisation de flux de travail, bien que la première fois, une boîte de dialogue apparaît pour vous demander d'autorisations.
- Hmm, intéressant. La première fois que vous avez autorisé l'application (lorsque la boîte de dialogue surgit), avez-vous eu des rappels de dire que la session est OUVERTE? Car une fois que vous auth l'application, le code que vous avez ici l'auto ouvrir la session dans la suite redémarrage de l'application.
- Non, il a dit "d'OUVERTURE".
- Généralement à l'absence d'un état de transition est révélateur de la suite de ne pas être passé sur la session (c'est à dire onActivityResult pas être appelé). Mais ton code a l'air bien et il n'y a pas de problèmes évidents. Pouvez-vous essayer de supprimer votre application à partir de l'appareil, de le réinstaller, de passer par la auth (lorsque vous obtenez la boîte de dialogue), et assurez-vous que onActivityResult est appelée dans votre fragment?
- onCreate, onCreateView et onResume sont appelés dans MainFragment. Rien d'autre.
- OK, donc pour une raison quelconque, le onActivityResult n'est pas appelée sur votre Fragment. Vous pouvez poster votre code d'Activité (en particulier où vous créez le fragment)? Sinon, vous pouvez essayer de remplacer onActivityResult dans votre activité, et de la Session d'appel.getActiveSession().onActivityResult.
- void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Facebook si (savedInstanceState == null) { // Ajouter le fragment sur l'activité initiale de l'installation mainFragment = new MainFragment(); getSupportFragmentManager().beginTransaction() .ajouter(android.R.id.contenu, mainFragment).commit(); } else { // Ou de fixer le fragment de l'état restauré info mainFragment = (MainFragment) getSupportFragmentManager() .findFragmentById(android.R.id.le contenu); }
- onActivityResult est ni appelé dans MainFragment ni dans mon MainActivity.
- Correction: onActivityResult est appelé dans mon MainActivity. Cependant, j'ai ajouté "authButton.setFragment(this);" à MainFragment, donc onActivityResult devrait être appelé là-bas " selon la documentation.
- Ok, j'ai trouvé l'erreur... Mon MainActivity n'est pas une sous-classe de FragmentActivity mais certains de la classe de base que j'ai créé pour mon application. Cette classe de base, cependant, est une sous-classe de FragmentActivity. Je suppose que quelque chose s'est perdu par ce genre de configuration. Je vous remercie pour votre temps, @ming-li, vous m'a orienté dans la bonne direction - en quelque sorte 😉
- La difficulté avec cela. Si vous avez réellement vérifier exception dans
onSessionStateChange()
, vous verrez que ce n'est pas vraiment tout simplement coincé dans l'OUVERTURE. Cette exception contient: java.lang.UnsupportedOperationException: Session: une tentative a été faite pour ouvrir une session qui a une demande en attente. Ceci suggère que la fonction de rappel renvoie plus rapide que la connexion pourrait effectivement se produire.
Vous devez vous connecter pour publier un commentaire.
Ce n'était pas facile à comprendre. 🙂
Si vous avez réellement vérifier
exception
dansonSessionStateChange()
, vous verrez que ce n'est pas vraiment tout simplement coincé dansOPENING
. Cette exception contient: java.lang.UnsupportedOperationException: Session: une tentative a été faite pour ouvrir une session qui a une demande en attente.La raison j'ai finalement trouvé était que
onActivityResult()
n'était pas appelé. Il est de sa responsabilité de rappeler àuiHelper
et cet appel qui fera appel à la finition de la partie de la connexion, donc si elle n'est pas appelée, l'état resteOPENING
pour toujours. En dehors de l'évidente conseils ci-dessus, c'est ce que j'ai trouvé et ils sont tous nécessaires pour la connexion à:Assurez-vous d'utiliser les deux un fragment d'une activité, comme décrit dans le FB de la documentation. Même si le doc a fait allusion à une activité suffisante, il n'est pas. Vous avez besoin des deux, même si l'activité n'a rien d'autre, mais l'appel de la simple fragment.
Assurez-vous que vous n'avez pas une histoire ensemble de l'activité (ni dans le manifeste ni dans le code).
Assurez-vous de remplacer le fragment de la
onActivityResult()
que par la documentation. Et assurez-vous de remplacer le même dans l'activité:Oui, cela semble étrange, mais il ne fonctionne pas sans elle.
Enfin cela fonctionne pour moi. Les points clés était d'ajouter
et
Code à l'intérieur de Fragment:
J'ai eu le même problème. L'état a toujours été
OPENING
. S'avère que @Gabor a été wright.Lorsque l'état de session est
OPENING
une méthodeonActivityResult
est appelée, c'est sûr.Si vous utilisez un fragment,
onActivityResult
est appelé à l'ACTIVITÉ qui détient le fragment, et pas dans le fragment. Cela est dû au passé de contexte etc.Donc j'ai fait comme ceci:
Vérifier ce
onActivityResults
est appelée (par logcat) - juste pour s'assurer queDans la méthode ajouter une ligne
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
Notez que le paramètrethis
est un contexte d'activité.ET
Utiliser le
UiLifecycleHelper
'sonActivityResult
méthode, comme ceci:UiHelper.onActivityResult(requestCode, resultCode, data);
Plus iciSi quelqu'un d'autre est toujours à avoir ce problème peut être causé par des raisons impérieuses onActivityResult dans l'Activité et non de l'appel de la méthode super.
Activité
Fragment
Vous devez mettre en œuvre
onActivityResult
dans l'activité qui n'est pas dans le fragment.A travaillé pour moi.
Encore une autre raison de ce qui pourrait se produire (comme il l'a fait pour moi), c'est quand vous êtes à l'aide de
getChildFragmentManager()
- onActivityResult n'est pas passé à imbriquée Fragments, en raison de un bug.Cette (en ayant l'hébergement Fragment de col de sa réception onActivityResult à tous les enfants) est ce qui m'a aidé.
Mon Activité de
onActivityResult
est invoquée... Donc j'ai fait une très très mauvaise, le piratage n':df est mon fragment. Qui a fait la séance d'obtenir de l'ouvrir... c'est putain de fou. Très intéressé à trouver une meilleure solution pour cela.
Dans mon cas, j'ai essayé de modifier le fragment de la classe de
android.support.v4.app.Fragment
àandroid.app.Fragment
(je n'ai pas de soutien pré API-11 versions d'Android) et omis leFBAuthButton.setFragment(this);
déclaration. Qui a été fait à l'origine du problème.J'ai eu le même problème, j'ai désinstallé mon application et réinstallé et ça a fonctionné!