Android FacebookSDK inicio de sesión con la aplicación nativa de Facebook instalado pide permisos incluso después de que el usuario ya les ha dado

Condición: Dispositivo Android con apk nativo de Facebook instalado pero desconectado.

Cada vez que se cumple esta condición y el usuario intenta iniciar sesión utilizando el LoginButton de Facebook o hacerlo manualmente (ver más abajo), después de iniciar sesión, el SDK de Facebook siempre pide permiso para acceder a los datos de usuario, incluso si el usuario ya ha dado permiso .

Aquí está el código que estoy implementando en mi aplicación:

Versión 1 – Botón de inicio de sesión:

XML:

<com.facebook.widget.LoginButton android:id="@+id/login_button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> 

Java:

 private static final List<String> PERMISSIONS = Arrays.asList("email", "user_groups"); private UiLifecycleHelper uiHelper; @Override protected void onCreate(Bundle savedInstanceState){ uiHelper = new UiLifecycleHelper(this, callback); uiHelper.onCreate(savedInstanceState); loginButton = (LoginButton) findViewById(R.id.login_button); loginButton.setReadPermissions(PERMISSIONS); } private Session.StatusCallback callback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { //modify interface or something } }; 

Versión 2 – Manualmente

XML:

 <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button" android:onClick="buttonOnClick" android:text="Login" /> 

Java:

 private static final List<String> PERMISSIONS = Arrays.asList("email", "user_groups"); public void buttonOnClick(View v) { System.out.println("botaoOnClick"); Session session = Session.getActiveSession(); if (!session.isOpened() && !session.isClosed()) { System.out.println("session: " + session); session.openForRead(new Session.OpenRequest(this).setPermissions(PERMISSIONS).setCallback(callback)); } else { Session.openActiveSession(this, true, callback); } } private Session.StatusCallback callback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { //modify interface or something } }; 

Incluso las aplicaciones de ejemplo que vienen con sdk funciona de esta manera, pero ya he visto algunas otras aplicaciones (por ejemplo, Foursquare) funcionando de la manera que creo que es el comportamiento natural ( sólo pide permisos si el usuario no les ha dado ).

Entonces, ¿alguien sabe una manera de lograr el resultado deseado? Preferentemente sin editar el propio SDK de Facebook.

¡Gracias por adelantado!

Editar 1 : Información adicional: al comprobar la variable de sesión en el método de devolución de llamada, los permisos siempre vienen vacíos cuando se cumple la condición anterior. Si el usuario se niega a dar permiso (no por primera vez), e intenta iniciar sesión nuevamente, la sesión viene con los permisos que el usuario ya dio algún tiempo en el pasado, como se esperaba.

Edit 2 (el 2013-06-28) : He decidido cargar un video reproduciendo el tema, ya que no estoy tan seguro de que todo el mundo entienda lo que he querido decir en mi explicación.

Enlace aquí: http://www.youtube.com/watch?v=w4qJfoiVSsU

4 Solutions collect form web for “Android FacebookSDK inicio de sesión con la aplicación nativa de Facebook instalado pide permisos incluso después de que el usuario ya les ha dado”

Eso es probablemente porque tienes una falta de coincidencia de firma entre su aplicación (que supongo que está en modo de depuración) y su aplicación de Facebook asociada a su appID.

Básicamente debe asegurarse de que:

  1. La firma de tu aplicación Android que usa el sdk de Facebook se agrega al panel de aplicaciones de Facebook Panel de aplicaciones de Facebook Puede obtener fácilmente la firma de la aplicación utilizando keytool o agregando este código al método onCreate de su actividad:

     @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); try { PackageInfo info = getPackageManager().getPackageInfo( getPackageName(), PackageManager.GET_SIGNATURES); for (Signature signature : info.signatures) { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(signature.toByteArray()); Log.d("TAG", "Hash to copy ==> "+ Base64.encodeToString(md.digest(), Base64.DEFAULT)); } } catch (NameNotFoundException e) { } catch (NoSuchAlgorithmException e) { } } 
  2. La casilla de verificación de acceso de Facebook está habilitada

  3. Si no habilitas el modo sandbox, debes elegir una categoría en la página de detalles de la aplicación

  4. Por defecto el loginbutton utiliza el loginbehavior SingleSignOn, que básicamente te conectará como propietario de la aplicación facebook, te sugiero que utilices el que permite a cualquier usuario iniciar sesión en nombre de tu aplicación de Facebook. Para ello, basta con añadir esta línea después de establecer el permiso en el botón de inicio de sesión:

     loginButton.setReadPermissions(PERMISSIONS); loginButton.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); 

Si sigues teniendo problemas, te sugiero que leas este documento.

PS: Y FYI, si utiliza UiLifecycleHelper, no olvide anular los métodos de ciclo de vida de la actividad / fragmento principal y reenvíe las llamadas al UiLifecycleHelper como se indica en el javadoc.

Al usar esta clase, los clientes DEBEN llamar a todos los métodos públicos de los * métodos respectivos en una actividad o un fragmento. La omisión de llamar a todos los métodos * puede resultar en sesiones incorrectamente inicializadas o no inicializadas.

 @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onResume() { super.onResume(); uiHelper.onResume(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); uiHelper.onSaveInstanceState(outState); } @Override protected void onPause() { super.onPause(); uiHelper.onPause(); } @Override protected void onDestroy() { super.onDestroy(); uiHelper.onDestroy(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); uiHelper.onActivityResult(requestCode, resultCode, data); } 

Creo que los permisos de lectura se solicitan cada vez (o simplemente mostrar una ventana emergente diciendo que ya se han concedido), si la aplicación de Facebook no está instalada en el dispositivo.

Debe ser el comportamiento con el último SDK de Android.

¿Se dio cuenta de que con la aplicación instalada también?

He identificado dos causas para este problema.

  1. Necesito pasar permisos en el bloque else en la versión manual de tu código, es decir, openActiveSession (), Para esto estoy usando openForRead (op) con permisos.
  2. KeyHash no coincide, en este caso también login con éxito en el facebook por defecto, pero cada vez muestra el diálogo de permisos.

He creado KeyHash usando debug.keystore con el siguiente comando

 keytool -exportcert -alia s androiddebugkey -keystore debug.keystore | ope nssl sha1 -binary | openssl base64 private static final List<String> PERMISSIONS = Arrays.asList("email", "user_groups"); public void buttonOnClick(View v) { Log.e("SKFBDemo", "buttonOnClick"); Session session = Session.getActiveSession(); if (session != null && !session.isOpened() && !session.isClosed()) { Log.e("SKFBDemo", "Session is in Active"); session.openForRead(new Session.OpenRequest(this).setPermissions(PERMISSIONS).setCallback(callback)); } else { Log.e("SKFBDemo", "Session is null or not opened or closed"); OpenRequest op = new Session.OpenRequest(this); op.setPermissions(PERMISSIONS); session = new Builder(this).build(); session.addCallback(callback); Session.setActiveSession(session); session.openForRead(op); } } private Session.StatusCallback callback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { Log.e("SKFBDemo", "Session.StatusCallback state="+state.toString()); } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.e("SKFBDemo", "onActivityResult resultCode="+resultCode); if(resultCode == RESULT_OK && requestCode == Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE) { Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); final Session session = Session.getActiveSession(); if (session != null && !session.isClosed()) { Log.e("SKFBDemo", "Login successful"); } else { Log.e("SKFBDemo", "Facebook session not opened"); } } } 

He intentado con este código, es pedir diálogo de permiso sólo una vez y funciona bien.

Utilizo la versión manual con un ligero giro a la instrucción if en su función buttonOnClick.

 Session session = Session.getActiveSession(); boolean isReadAllowed = checkPermissions(Arrays.asList(PERMISSIONS), session.getPermissions()); if (!session.isOpened() && !session.isClosed()) { session.openForRead(new Session.OpenRequest(this).setPermissions(PERMISSIONS).setCallback(callback)); } else { if (isReadAllowed) { Session.openActiveSession(this, true, callback); } else { session.requestNewReadPermissions(new Session.NewPermissionsRequest(this, Arrays.asList(PERMISSIONS)).setCallback(callback)); } } 

Y mi función de checkPermissions:

 public static boolean checkPermissions(List<String> needed, List<String> available) { boolean ret = true; for (String s : needed) { if (!available.contains(s)) { ret = false; break; } } return ret; } 

Mi flujo funciona y sólo pide permisos si no se han concedido. ¿Puede pegar más de su código de devolución de llamada? Puedo comprobar si estás haciendo algo diferente.

EDIT: Gracias por el video. No entendí el problema inicialmente. He visto este comportamiento antes, y es un error con el SDK de Facebook. Archivé un error en su rastreador ( enlace ) hace un mes, no parece que van a arreglarlo.

  • La aplicación de Android tiene una marca de exclamación roja en Eclipse después de importar la biblioteca de Facebook
  • Facebook Android SDK v4.0.0 ShareDialog NullPointerException issue
  • Recuperar foto de perfil con Facebook SDK 3.0 para Android
  • La aplicación de Android con Facebook no funciona con la aplicación de Facebook instalada
  • Android - Facebook SDK 3 - Cómo iniciar sesión mediante programación sin LoginButton
  • ClassNotFoundException para com.facebook.FacebookActivity
  • Android facebook sdk no llama a la devolución de llamada después de iniciar sesión
  • "No se puede resolver el símbolo` Request` 'error para facebook Graph API
  • Android: Cómo obtener la imagen de usuario de facebook mediante access_token
  • Android: el inicio de sesión de Facebook provoca error de onResume sólo por primera vez
  • Parece que no tiene recursos de Facebook SDK cuando usa Facebook Android SDK en IntelliJ IDEA 12
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.