Ich habe viel über stackoverflow gesucht, aber ich konnte keine Antwort finden, die mein Problem löst. Daher poste ich dies.
Ich habe ein Beispiel für eine Android-App, in der ich Facebook Login verwenden möchte. Hier sind die Schritte, die ich befolgt habe:
Umgebung: Android StudioAndroid-SDK-Version: 22 Facebook-SDK: 4.0
Befolgen Sie die Schritte zur Installation von FB APK auf dem Emulator, generieren Sie den Developer-Hash-Schlüssel und aktualisieren Sie ihn in app-> settings . Mein Android-Manifest enthält diesen Code
<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"/>
In meiner Layoutdatei "activity_main.xml" habe ich diesen 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" />
Und zum Schluss habe ich das in meiner Hauptaktivität
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);
}}
Ich bekomme eine Nullzeiger-Ausnahme wie unten gezeigt
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)
Was fehlt mir hier?
Anscheinend erhalten Sie eine NullPointerException
, da Sie findViewById()
aufrufen, bevor Sie setContentView()
aufrufen. Daher ist loginButton
null, wenn Sie loginButton.registerCallback()
aufrufen.
Verschieben Sie einfach den Aufruf an setContentView()
nach oben:
@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);
}
});
}
Der Absturz scheint mit der applicationId in Zusammenhang zu stehen, die wir in der AndoridMenifest.xml
-Datei einstellen. Als ich herausfand, dass wenn facebook sdk die LoginFramment
erstellt, dann ApplicationId als null
.hier kommt, gibt es die onCreate-Methode der com.facebook.login.LoginFragment
-Klasse
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");
}
}
}
Wie der varoius-Beitrag darauf hinweist, kommt die applicationId zu null, da die Zeichenfolgenressource app_id
von Android nicht richtig analysiert wird . https://github.com/jamesward/AndroidStringBug
Ich habe dieses Problem gelöst, indem Sie die applicationId manuell eingestellt haben, nachdem Sie die facebook-sdk wie folgt in der onCreate
-Methode initialisiert haben.
FacebookSdk.sdkInitialize(getApplicationContext());
FacebookSdk.setApplicationId(getResources().getString(R.string.app_id));
mFacebookCallbackManager = CallbackManager.Factory.create();
als anj unbestimmtes problem ist in der regel mit der ApplicationId nicht gelesen worden. In meinem Fall war das Problem mit dem Namespace. Stellen Sie sicher, dass Ihr Namespace der Klasse der Root-Namespace ist. Meine App ist also eine Xamarin-Android-App, und ich verwendete den Namespace wie folgt, aber der Namespace meiner Android-App ist myApp.Droid. Auf diese Weise wird ApplicaitonId nicht aus strings.xml gelesen, wenn zu myApp.Droid geändert wird. Ich hoffe, es hilft allen anderen, die ein ähnliches Problem haben
[Assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/app_id")]
namespace myApp.Droid.Renderer