¿Cuándo solicitar permisos con el nuevo Android SDK 3.0 de Facebook?

Con el nuevo Android SDK 3.0 de Facebook (que se lanzó hace unos días), el proceso de autenticación ha cambiado.

Entonces, ¿cómo solicitas un permiso de lectura como “friends_hometown”?

El siguiente código es cómo trato de hacerlo, pero estoy bastante seguro de que no es la forma en que debes hacer esto:

Versión 1:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Session.openActiveSession(this, true, new Session.StatusCallback() { // start Facebook login @Override public void call(Session session, SessionState state, Exception exception) { // callback for session state changes if (session.isOpened()) { List permissions = new ArrayList(); permissions.add("friends_hometown"); session.requestNewReadPermissions(new Session.NewPermissionsRequest(FBImport.this, permissions)); Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown", new Request.Callback() { ... }); } } }); } 

Versión 2:

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Session currentSession = Session.getActiveSession(); if (currentSession == null || currentSession.getState().isClosed()) { Session session = Session.openActiveSession(this, true, fbStatusCallback); // PROBLEM: NO PERMISSIONS YET BUT CALLBACK IS EXECUTED ON OPEN currentSession = session; } if (currentSession != null && !currentSession.isOpened()) { OpenRequest openRequest = new OpenRequest(this).setCallback(fbStatusCallback); // HERE IT IS OKAY TO EXECUTE THE CALLBACK BECAUSE WE'VE GOT THE PERMISSIONS if (openRequest != null) { openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS); openRequest.setPermissions(Arrays.asList("friends_hometown")); openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK); currentSession.openForRead(openRequest); } } } 

Lo que estoy haciendo es solicitar el permiso tan pronto como la sesión esté abierta, pero en este momento el código ya está comenzando una solicitud Graph API, por lo que la solicitud de permiso llega tarde …

¿No puedes solicitar un permiso al mismo tiempo que inicias la sesión?

Recomiendo que lea nuestro tutorial de inicio de sesión aquí específicamente en el paso 3. El uso del botón de inicio de sesión que proporcionamos es el método más conveniente (ver authButton.setReadPermissions() )

EDITAR:

Establecer permisos sin usar el botón de inicio de sesión es más complicado, ya que tendrá que hacer toda la administración de la sesión a mano. Indagando en el código fuente para el botón de inicio de sesión, esta línea de código es probablemente lo que necesita. Parece que deberá crear su propia Session.OpenRequest y establecer sus atributos como permisos, audiencia y comportamiento de inicio de sesión, luego obtener la sesión actual y llamar a openForRead() en su Session.OpenRequest .

Pude hacer que funcionara. Es una modificación de tu muestra de la Versión 2. El enlace que proporcionó Jesse también ayudó mucho.

Aquí está el código que corro cuando autentico a un usuario:

 private void signInWithFacebook() { mSessionTracker = new SessionTracker(getBaseContext(), new StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { } }, null, false); String applicationId = Utility.getMetadataApplicationId(getBaseContext()); mCurrentSession = mSessionTracker.getSession(); if (mCurrentSession == null || mCurrentSession.getState().isClosed()) { mSessionTracker.setSession(null); Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build(); Session.setActiveSession(session); mCurrentSession = session; } if (!mCurrentSession.isOpened()) { Session.OpenRequest openRequest = null; openRequest = new Session.OpenRequest(SignUpChoices.this); if (openRequest != null) { openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS); openRequest.setPermissions(Arrays.asList("user_birthday", "email", "user_location")); openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK); mCurrentSession.openForRead(openRequest); } }else { Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() { @Override public void onCompleted(GraphUser user, Response response) { Log.w("myConsultant", user.getId() + " " + user.getName() + " " + user.getInnerJSONObject()); } }); } } 

Para las pruebas lo ejecuté a través del siguiente código después de regresar de la autenticación de Facebook:

 public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); if (mCurrentSession.isOpened()) { Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() { // callback after Graph API response with user object @Override public void onCompleted(GraphUser user, Response response) { Log.w("myConsultant", user.getId() + " " + user.getName() + " " + user.getInnerJSONObject()); } }); } } 

Resolví el mismo problema implementando mi propio método Session.openActiveSession() :

 private static Session openActiveSession(Activity activity, boolean allowLoginUI, StatusCallback callback, List permissions) { OpenRequest openRequest = new OpenRequest(activity).setPermissions(permissions).setCallback(callback); Session session = new Builder(activity).build(); if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) { Session.setActiveSession(session); session.openForRead(openRequest); return session; } return null; } 

Aunque la primera pregunta se realizó hace unos meses y hay respuestas aceptadas, hay otra solución más elegante para solicitar más permisos del usuario durante la autenticación. Además, Facebook SDK 3.5 fue lanzado recientemente y sería bueno actualizar este hilo 🙂

Por lo tanto, la solución elegante viene con esta biblioteca de código abierto: android-simple-facebook

Preparar

Solo agrega las siguientes líneas en tu clase de Activity :

  1. Defina y seleccione los permisos que necesita, como friends_hometown :

     Permissions[] permissions = new Permissions[] { Permissions.FRIENDS_HOMETOWN, Permissions.FRIENDS_PHOTOS, Permissions.PUBLISH_ACTION }; 

    Lo bueno aquí con los permisos es que no necesita separar los permisos LEER y PUBLICAR. Simplemente mencione lo que necesita y la biblioteca se encargará del rest.

  2. Cree y defina la configuración poniendo app_id , namespace y permissions :

     SimpleFacebookConfiguration configuration = new SimpleFacebookConfiguration.Builder() .setAppId("625994234086470") .setNamespace("sromkuapp") .setPermissions(permissions) .build(); 
  3. Y crea una instancia de SimpleFacebook y configura esta configuración:

     SimpleFacebook simpleFacebook = SimpleFacebook.getInstance(Activity); simpleFacebook.setConfiguration(configuration); 

Ahora puede ejecutar los métodos como: iniciar sesión , publicar feed / historia , invitar , …

Iniciar sesión

 mSimpleFacebook.login(OnLoginListener); 

Cerrar sesión

 mSimpleFacebook.logout(OnLogoutListener); 

Para obtener más ejemplos y uso, consulte esta página: https://github.com/sromku/android-simple-facebook#actions-examples