J'ai beaucoup cherché dans stackoverflow mais je n'ai pas trouvé de réponse qui résout mon problème. Par conséquent, je poste ceci.
J'ai un exemple d'application Android dans lequel j'essaie d'utiliser Facebook Login. Voici les étapes que j'ai suivies:
Environnement: Android studio Version du SDK Android: 22 Facebook SDK: 4.0
Suivre les étapes pour installer FB APK sur l'émulateur, générer la clé de hachage développeur et la mettre à jour dans app-> paramètres .
<uses-permission Android:name="Android.permission.INTERNET"/>
<activity Android:name="com.facebook.FacebookActivity"
Android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
Android:theme="@Android:style/Theme.Translucent.NoTitleBar" Android:label="@string/app_name" />
<meta-data Android:name="com.facebook.sdk.ApplicationId" Android:value="@string/facebook_app_id"/>
Dans mon fichier de mise en forme activity_main.xml, j'ai ce morceau de code
<com.facebook.login.widget.LoginButton
Android:id="@+id/fblogin_button"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center_horizontal"
Android:layout_marginTop="30dp"
Android:layout_marginBottom="30dp" />
Et enfin dans mon activité principale j'ai
public class MainActivity extends Activity {
LoginButton loginButton;
CallbackManager callbackManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.fblogin_button);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Toast.makeText(getApplicationContext(),"Fb Login Success",Toast.LENGTH_LONG);
}
@Override
public void onCancel() {
Toast.makeText(getApplicationContext(),"Fb on cancel",Toast.LENGTH_LONG);
}
@Override
public void onError(FacebookException e) {
Toast.makeText(getApplicationContext(),"Fb Login Error",Toast.LENGTH_LONG);
}
});
setContentView(R.layout.activity_main);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
Log.d("Inside Fb login","on Activiry result");
callbackManager.onActivityResult(requestCode, resultCode, data);
}}
Je reçois une exception de pointeur nul comme indiqué ci-dessous
Java.lang.RuntimeException: Unable to start activity componentInfo{PROJECT.MainActivity}: Java.lang.NullPointerException: Attempt to invoke virtual method 'void com.facebook.login.widget.LoginButton.registerCallback(com.facebook.CallbackManager, com.facebook.FacebookCallback)' on a null object reference
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2298)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2360)
at Android.app.ActivityThread.access$800(ActivityThread.Java:144)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1278)
at Android.os.Handler.dispatchMessage(Handler.Java:102)
at Android.os.Looper.loop(Looper.Java:135)
at Android.app.ActivityThread.main(ActivityThread.Java:5221)
at Java.lang.reflect.Method.invoke(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:372)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:899)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:694)
Qu'est-ce que j'oublie ici ?
On dirait que vous obtenez une NullPointerException
parce que vous appelez findViewById()
avant d'appeler setContentView()
, donc loginButton
est nul lorsque vous appelez loginButton.registerCallback()
.
Il suffit de déplacer l'appel vers setContentView()
vers le haut:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
setContentView(R.layout.activity_main); //Moved up here to resolve NPE
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.fblogin_button);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Toast.makeText(getApplicationContext(),"Fb Login Success",Toast.LENGTH_LONG);
}
@Override
public void onCancel() {
Toast.makeText(getApplicationContext(),"Fb on cancel",Toast.LENGTH_LONG);
}
@Override
public void onError(FacebookException e) {
Toast.makeText(getApplicationContext(),"Fb Login Error",Toast.LENGTH_LONG);
}
});
}
L’incident semble être lié à l’applicationId que nous définissons dans le fichier AndoridMenifest.xml
. Comme je l'ai compris, lorsque facebook sdk crée un LoginFramment
, ApplicationId arrive en tant que null
.Voici la méthode onCreate de la classe com.facebook.login.LoginFragment
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
this.loginClient = (LoginClient)savedInstanceState.getParcelable("loginClient");
this.loginClient.setFragment(this);
} else {
this.loginClient = new LoginClient(this);
}
this.loginClient.setOnCompletedListener(new OnCompletedListener() {
public void onCompleted(Result outcome) {
LoginFragment.this.onLoginClientCompleted(outcome);
}
});
FragmentActivity activity = this.getActivity();
if(activity != null) {
this.initializeCallingPackage(activity);
if(activity.getIntent() != null) {
//the applicationId in this.request object is null
this.request = (Request)activity.getIntent().getParcelableExtra("request");
}
}
}
Comme indiqué par le message suivant, applicationId arrive à zéro, car la ressource chaîne app_id
n'est pas analysée correctement par Android . https://github.com/jamesward/AndroidStringBug
J'ai résolu ce problème en définissant manuellement applicationId après l'initialisation du sdk de facebook, comme indiqué ci-dessous dans la méthode onCreate
.
FacebookSdk.sdkInitialize(getApplicationContext());
FacebookSdk.setApplicationId(getResources().getString(R.string.app_id));
mFacebookCallbackManager = CallbackManager.Factory.create();
comme anj indiqué le problème est généralement avec le ApplicationId n'a pas été lu. dans mon cas, le problème était avec l'espace de noms. assurez-vous que votre espace de noms de la classe est l'espace de noms racine. Donc, mon application est une application Android xamarin et j'utilisais un espace de noms comme ci-dessous, mais l'espace de noms de mon application Android est myApp.Droid. De cette façon, ApplicaitonId n'est pas lu à partir de strings.xml, le changement en myApp.Droid a résolu mon problème. J'espère que cela aidera tout le monde ayant le même problème
[Assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/app_id")]
namespace myApp.Droid.Renderer