Facebook SDK 3.0 para Android sin Fragmentos no funciona
Me gustaría usar Facebook SDK 3.0 para Android para hacer algunas solicitudes de gráficos simples. Como no utilizaré Fragment
s, no puedo usar las muestras que se publican en la documentación de desarrolladores de Facebook.
Ya tenía algunas Activity
simples configuradas, pero no funcionaron. He hecho preguntas con generosidad aquí y aquí . Pero eso no ayudó realmente.
- Cómo obtener la foto del perfil de facebook en facebook SDK 3.0 Android
- Acceso autenticado a WebAPI a través del token de Facebook de la aplicación para Android
- Error de Android aleatoriamente java.lang.NoClassDefFoundError: com.facebook.internal.Utility
- Facebook SDK: invalide alcance: información básica use public_profile, amigos de usuario en su lugar
- El inicio de sesión de Facebook falla en algunos dispositivos
Mientras tanto, he estado leyendo un montón de publicaciones sobre el SDK de Facebook y he intentado durante decenas de horas, pero sin éxito. Finalmente, encontré un ejemplo de código adicional en este blog . Así que he configurado una Activity
completa que es para imprimir la ciudad natal de todos los amigos a LogCat.
Pero esto tampoco funciona. En su lugar, pide los permisos básicos (información pública + lista de amigos) y luego se cierra. ¿Qué estoy haciendo mal? El hash clave, el nombre del paquete y el nombre de la clase para la aplicación de Facebook se establecen y no hay nada interesante impreso en LogCat.
package com.my.package; import java.util.Arrays; import java.util.Date; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.widget.Toast; import com.facebook.*; public class FBRequest extends Activity { private static final String PERMISSION_FRIENDS_HOMETOWN = "friends_hometown"; private static final String PREFERENCE_ACCESS_TOKEN = "facebookAccessToken"; private static final String PREFERENCE_EXPIRATION_DATE = "facebookAccessTokenExpires"; private ProgressDialog mProgress; private SharedPreferences mPrefs; private void showToast(final String text) { runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show(); } }); } protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPrefs = PreferenceManager.getDefaultSharedPreferences(this); try { startFacebookRequest(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Session session = Session.getActiveSession(); if (session != null) { session.onActivityResult(this, requestCode, resultCode, data); } } public interface FacebookConnectHandler { public void onSuccess(); public void onFailure(); } public void startFacebookRequest() { connectToFacebook(new FacebookConnectHandler() { @Override public void onSuccess() { // safety check if (isFinishing()) { return; } showProgressDialog("Connecting to Facebook ..."); // check for publish permissions final List<String> permissions_required = Arrays.asList(PERMISSION_FRIENDS_HOMETOWN); if (Session.getActiveSession().getPermissions() == null || !Session.getActiveSession().getPermissions().containsAll(permissions_required)) { // need to make a Session.openActiveSessionFromCache(...) call // because of a bug in the Facebook sdk // where a second call to get permissions // won't result in a session callback when the token is updated if (Session.openActiveSessionFromCache(FBRequest.this) == null) { showToast("Could not connect to Facebook! (3)"); return; } Session.getActiveSession().addCallback(new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { if (exception != null || state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { // didn't get required permissions session.removeCallback(this); // safety check if (!isFinishing()) { showToast("Could not connect to Facebook! (4)"); } } else if (state.equals(SessionState.OPENED_TOKEN_UPDATED) && session.getPermissions().containsAll(permissions_required)) { // got required permissions session.removeCallback(this); // safety check if (!isFinishing()) { startFacebookRequest(); } } } }); Session.getActiveSession().requestNewReadPermissions(new Session.NewPermissionsRequest(FBRequest.this, permissions_required)); return; } startGraphRequest(Session.getActiveSession()); } @Override public void onFailure() { cancelProgressDialog(); showToast("Could not connect to Facebook! (1)"); } }); } private void startGraphRequest(Session session) { Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown&limit=500", new Request.Callback() { @Override public void onCompleted(Response response) { if (response != null) { try { JSONArray jarr = response.getGraphObject().getInnerJSONObject().getJSONArray("data"); JSONObject entry; StringBuilder backupStr = new StringBuilder(); int nExistingEntries = existingEntries.length; for (int i = 0; i < jarr.length(); i++) { entry = jarr.getJSONObject(i); if (!entry.isNull("id") && !entry.isNull("name") && !entry.isNull("hometown")) { System.out.println(entry.getString("hometown")); } } } catch (Exception e) { e.printStackTrace(); showToast("Unexpected error!"); } } } }); } private void connectToFacebook(final FacebookConnectHandler handler) { // check whether the user already has an active session // and try opening it if we do // (note: making a Session.openActiveSessionFromCache(...) call // instead of simply checking whether the active session is opened // because of a bug in the Facebook sdk // where successive calls to update a token // (requesting additional permissions etc) // don't result in a session callback) if (Session.getActiveSession() != null && Session.openActiveSessionFromCache(this) != null) { handler.onSuccess(); return; } // initialise the session status callback Session.StatusCallback callback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { if (isFinishing()) { return; } // check session state if (state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { clearFacebookSharedPreferences(); // specific action for when the session is closed // because an open-session request failed if (state.equals(SessionState.CLOSED_LOGIN_FAILED)) { cancelProgressDialog(); handler.onFailure(); } } else if (state.equals(SessionState.OPENED)) { cancelProgressDialog(); saveFacebookSharedPreferences(session.getAccessToken(), session.getExpirationDate().getTime()); showToast("Succeeded connecting to Facebook"); handler.onSuccess(); } } }; // make the call to open the session showProgressDialog("Connecting to Facebook..."); if (Session.getActiveSession() == null && mPrefs.contains(PREFERENCE_ACCESS_TOKEN) && mPrefs.contains(PREFERENCE_EXPIRATION_DATE)) { // open a session from the access token info // saved in the app's shared preferences String accessTokenString = mPrefs.getString(PREFERENCE_ACCESS_TOKEN, ""); Date accessTokenExpires = new Date(mPrefs.getLong(PREFERENCE_EXPIRATION_DATE, 0)); AccessToken accessToken = AccessToken.createFromExistingAccessToken(accessTokenString, accessTokenExpires, null, null, null); Session.openActiveSessionWithAccessToken(this, accessToken, callback); } else { // open a new session, logging in if necessary Session.openActiveSession(this, true, callback); } } private void saveFacebookSharedPreferences(final String token, final long expiration) { if (mPrefs != null) { SharedPreferences.Editor editor = mPrefs.edit(); editor.putString(PREFERENCE_ACCESS_TOKEN, token); editor.putLong(PREFERENCE_EXPIRATION_DATE, expiration); editor.commit(); } } private void clearFacebookSharedPreferences() { if (mPrefs != null) { SharedPreferences.Editor editor = mPrefs.edit(); editor.remove(PREFERENCE_ACCESS_TOKEN); editor.remove(PREFERENCE_EXPIRATION_DATE); editor.commit(); } } private void showProgressDialog(final String text) { mProgress = ProgressDialog.show(getApplicationContext(), "Facebook", text, true, false); } private void cancelProgressDialog() { if (mProgress != null) { if (mProgress.isShowing()) { mProgress.dismiss(); } mProgress = null; } } @Override protected void onDestroy() { super.onDestroy(); cancelProgressDialog(); } }
¡Gracias por adelantado!
Edit: El código funcionó, pero yo no había llamado setContentView()
y el setContentView()
la Activity
fue llamado en un caso de error. Esta es la razón por la que uno no pudo ver la segunda solicitud de permisos (ampliados).
- Android - Facebook ShareDialog desaparece pocos segundos después de que se muestre
- NPE en Facebook SDK 4.10: Intenta invocar el método de interfaz 'java.lang.Object com.facebook.inject.Lazy.get ()' en una referencia de objeto nulo
- Solicitud de Amigos en Facebook - Amigos Desaparecidos
- ¿Cómo detectar un evento de cierre de sesión con la API de Android de Facebook v4?
- Session: se ha intentado solicitar nuevos permisos para una sesión que tiene una petición pendiente
- Buck - java.lang.UnsatisfiedLinkError: no pudo encontrar "libjni.so". ¿Cómo resolverlo?
- CLOSED_LOGIN_FAILED y FacebookOperationCanceledException
- El token de acceso extendido de Facebook no funciona correctamente
El código anterior está funcionando bien, excepto pequeños cambios que hice, es decir, mientras que muestra el diálogo de progreso de su ventana de excepción dando mal símbolo para esto he cambiado el contexto . y también comenté una línea que no se utiliza 'existingEntries'.
Soy capaz de iniciar sesión y la aplicación pidió permiso para acceder a amigos acceso a la ciudad natal. Puedo ver ids amigo y con sus ciudades de origen.
Versión de trabajo actualizada:
package com.example.options; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.widget.Toast; import com.facebook.AccessToken; import com.facebook.Request; import com.facebook.Response; import com.facebook.Session; import com.facebook.Session.Builder; import com.facebook.Session.NewPermissionsRequest; import com.facebook.Session.OpenRequest; import com.facebook.SessionLoginBehavior; import com.facebook.SessionState; public class FBRequest extends Activity { private static final String PERMISSION_FRIENDS_HOMETOWN = "friends_hometown"; private static final String PREFERENCE_ACCESS_TOKEN = "facebookAccessToken"; private static final String PREFERENCE_EXPIRATION_DATE = "facebookAccessTokenExpires"; private ProgressDialog mProgress; private SharedPreferences mPrefs; private void showToast(final String text) { runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show(); } }); } protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPrefs = PreferenceManager.getDefaultSharedPreferences(this); try { startFacebookRequest(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK && requestCode == Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE) { Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); Session session = Session.getActiveSession(); if (session != null && !session.isClosed()) { startFacebookRequest(); } } } public interface FacebookConnectHandler { public void onSuccess(); public void onFailure(); } public void startFacebookRequest() { connectToFacebook(new FacebookConnectHandler() { @Override public void onSuccess() { // safety check if (isFinishing()) { return; } showProgressDialog("Connecting to Facebook ..."); // check for publish permissions final List<String> permissions_required = Arrays.asList(PERMISSION_FRIENDS_HOMETOWN); if (Session.getActiveSession().getPermissions() == null || !Session.getActiveSession().getPermissions().containsAll(permissions_required)) { // need to make a Session.openActiveSessionFromCache(...) call // because of a bug in the Facebook sdk // where a second call to get permissions // won't result in a session callback when the token is updated if (Session.openActiveSessionFromCache(FBRequest.this) == null) { showToast("Could not connect to Facebook! (3)"); return; } Session.getActiveSession().addCallback(new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { if (exception != null || state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { // didn't get required permissions session.removeCallback(this); // safety check if (!isFinishing()) { showToast("Could not connect to Facebook! (4)"); } } else if (state.equals(SessionState.OPENED_TOKEN_UPDATED) && session.getPermissions().containsAll(permissions_required)) { // got required permissions session.removeCallback(this); // safety check if (!isFinishing()) { startFacebookRequest(); } } } }); NewPermissionsRequest req = new Session.NewPermissionsRequest(FBRequest.this, permissions_required); req.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); Session.getActiveSession().requestNewReadPermissions(req); return; } startGraphRequest(Session.getActiveSession()); } @Override public void onFailure() { cancelProgressDialog(); showToast("Could not connect to Facebook! (1)"); } }); } private void startGraphRequest(Session session) { Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown&limit=500", new Request.Callback() { @Override public void onCompleted(Response response) { if (response != null) { try { JSONArray jarr = response.getGraphObject().getInnerJSONObject().getJSONArray("data"); JSONObject entry; StringBuilder backupStr = new StringBuilder(); // int nExistingEntries = existingEntries.length; for (int i = 0; i < jarr.length(); i++) { entry = jarr.getJSONObject(i); if (!entry.isNull("id") && !entry.isNull("name") && !entry.isNull("hometown")) { System.out.println(entry.getString("hometown")); } } } catch (Exception e) { e.printStackTrace(); showToast("Unexpected error!"); } showToast("Friends list populated"); cancelProgressDialog(); } } }); } private void connectToFacebook(final FacebookConnectHandler handler) { // check whether the user already has an active session // and try opening it if we do // (note: making a Session.openActiveSessionFromCache(...) call // instead of simply checking whether the active session is opened // because of a bug in the Facebook sdk // where successive calls to update a token // (requesting additional permissions etc) // don't result in a session callback) if (Session.getActiveSession() != null && Session.openActiveSessionFromCache(this) != null) { handler.onSuccess(); return; } // initialise the session status callback Session.StatusCallback callback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { if (isFinishing()) { return; } // check session state if (state.equals(SessionState.CLOSED) || state.equals(SessionState.CLOSED_LOGIN_FAILED)) { clearFacebookSharedPreferences(); // specific action for when the session is closed // because an open-session request failed if (state.equals(SessionState.CLOSED_LOGIN_FAILED)) { cancelProgressDialog(); handler.onFailure(); } } else if (state.equals(SessionState.OPENED)) { cancelProgressDialog(); saveFacebookSharedPreferences(session.getAccessToken(), session.getExpirationDate().getTime()); showToast("Succeeded connecting to Facebook"); handler.onSuccess(); } } }; // make the call to open the session showProgressDialog("Connecting to Facebook..."); if (Session.getActiveSession() == null && mPrefs.contains(PREFERENCE_ACCESS_TOKEN) && mPrefs.contains(PREFERENCE_EXPIRATION_DATE)) { // open a session from the access token info // saved in the app's shared preferences String accessTokenString = mPrefs.getString(PREFERENCE_ACCESS_TOKEN, ""); Date accessTokenExpires = new Date(mPrefs.getLong(PREFERENCE_EXPIRATION_DATE, 0)); AccessToken accessToken = AccessToken.createFromExistingAccessToken(accessTokenString, accessTokenExpires, null, null, null); Session.openActiveSessionWithAccessToken(this, accessToken, callback); } else { // open a new session, logging in if necessary OpenRequest op = new Session.OpenRequest(this); op.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); op.setCallback(null); List<String> permissions = new ArrayList<String>(); permissions.add(PERMISSION_FRIENDS_HOMETOWN); op.setPermissions(permissions); Session session = new Builder(this).build(); Session.setActiveSession(session); session.openForRead(op); } } private void saveFacebookSharedPreferences(final String token, final long expiration) { if (mPrefs != null) { SharedPreferences.Editor editor = mPrefs.edit(); editor.putString(PREFERENCE_ACCESS_TOKEN, token); editor.putLong(PREFERENCE_EXPIRATION_DATE, expiration); editor.commit(); } } private void clearFacebookSharedPreferences() { if (mPrefs != null) { SharedPreferences.Editor editor = mPrefs.edit(); editor.remove(PREFERENCE_ACCESS_TOKEN); editor.remove(PREFERENCE_EXPIRATION_DATE); editor.commit(); } } private void showProgressDialog(final String text) { cancelProgressDialog(); mProgress = ProgressDialog.show(FBRequest.this, "Facebook", text, true, false); } private void cancelProgressDialog() { if (mProgress != null) { if (mProgress.isShowing()) { mProgress.dismiss(); } mProgress = null; } } @Override protected void onDestroy() { super.onDestroy(); cancelProgressDialog(); } }
Logcat:
...... ...... 03-11 18:57:26.781: I/System.out(6729): {"id":"10555075614xxxx","name":"Khammam"} 03-11 18:57:26.781: I/System.out(6729): {"id":"11042167564xxxx","name":"Warangal, India"} 03-11 18:57:26.789: I/System.out(6729): {"id":"11042167564xxxx","name":"Warangal, India"} 03-11 18:57:26.796: I/System.out(6729): {"id":"13074615695xxxx","name":"Jaggayyapet, India"} 03-11 18:57:26.812: I/System.out(6729): {"id":"12530386417xxxx","name":"Kodada, India"} 03-11 18:57:26.812: I/System.out(6729): {"id":"11047265564xxxx","name":"Vishakhapatnam, Andhra Pradesh, India"}
Actualizaciones:
En el inicio de sesión de inicio de sesión pide todos los permisos, y eliminado SSO inicio de sesión porque no he configurado mi aplicación de Facebook con la aplicación nativa (con keystore hash clave).
USE siguiente facebook SDK https://github.com/facebook/facebook-android-sdk/
El siguiente es el código para su requisito (obtener lista de amigos de facebook)
try { Facebook mFacebook = new Facebook(Constants.FB_APP_ID); AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(mFacebook); Bundle bundle = new Bundle(); bundle.putString("fields", "birthday"); mFacebook.request("me/friends", bundle, new FriendListRequestListener()); } catch(Exception e){ Log.e(Constants.LOGTAG, " " + CLASSTAG + " Exception = "+e.getMessage()); } public class FriendListRequestListener extends BaseRequestListener { public void onComplete(final String response) { _error = null; try { JSONObject json = Util.parseJson(response); final JSONArray friends = json.getJSONArray("data"); FacebookActivity.this.runOnUiThread(new Runnable() { public void run() { // Do stuff here with your friends array, // which is an array of JSONObjects. } }); } catch (JSONException e) { _error = "JSON Error in response"; } catch (FacebookError e) { _error = "Facebook Error: " + e.getMessage(); } if (_error != null) { FacebookActivity.this.runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), "Error occurred: " + _error, Toast.LENGTH_LONG).show(); } }); } } }
Espero que te ayude a ti ya otros.
- ¿Por qué Android no puede lidiar con el conflicto de nombres de recursos entre Project y Library?
- android: make imageview tamaño de pantalla completa