0

我想爲我的移動應用程序整合Facebook和Google身份驗證。我已經跟隨谷歌和Facebook的教程如何做到這一點,兩個項目分開時都能正常工作。在我目前的解決方案簽署在與谷歌工作正常但Facebook給了我以下錯誤信息:Facebook和谷歌身份驗證內的Android應用程序

Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL 

E/Parcel: Class not found when unmarshalling: com.facebook.login.LoginClient$Request 

Caused by: java.lang.NoClassDefFoundError: com/facebook/login/LoginClient$Request 

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.facebook.login.LoginClient$Request" on path 

這裏是我的LoginAvtivity I類用於身份驗證:

public class ActivityLogin extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { 

private static final String TAG = "SignInActivity"; 
private static final int RC_SIGN_IN = 9001; 

private GoogleApiClient mGoogleApiClient; 
private ProgressDialog mProgressDialog; 

private LoginButton facebookButton; 
private CallbackManager facebookCallbackManager; 

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    FacebookSdk.sdkInitialize(getApplicationContext()); 
    facebookCallbackManager = CallbackManager.Factory.create(); 
    setContentView(R.layout.activity_login); 




    // Button listeners 
    findViewById(R.id.google_button).setOnClickListener(this); 
    facebookButton = (LoginButton)findViewById(R.id.facebook_button); 

    // [START configure_signin] 
    // Configure sign-in to request the user's ID, email address, and basic 
    // profile. ID and basic profile are included in DEFAULT_SIGN_IN. 
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
      .requestEmail() 
      .requestIdToken(getString(R.string.server_client_id)) 
      .build(); 

    // [START build_client] 
    // Build a GoogleApiClient with access to the Google Sign-In API and the 
    // options specified by gso. 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) 
      .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 
      .build(); 

    // [START customize_button] 
    // Customize sign-in button. The sign-in button can be displayed in 
    // multiple sizes and color schemes. It can also be contextually 
    // rendered based on the requested scopes. For example. a red button may 
    // be displayed when Google+ scopes are requested, but a white button 
    // may be displayed when only basic profile is requested. Try adding the 
    // Scopes.PLUS_LOGIN scope to the GoogleSignInOptions to see the 
    // difference. 
    SignInButton signInButton = (SignInButton) findViewById(R.id.google_button); 
    signInButton.setSize(SignInButton.SIZE_STANDARD); 
    signInButton.setScopes(gso.getScopeArray()); 

    setGooglePlusButtonText(signInButton, "Sign in with Google"); 

    facebookButton.registerCallback(facebookCallbackManager, new FacebookCallback<LoginResult>() { 
     @Override 
     public void onSuccess(LoginResult loginResult) { 
      Intent intent = new Intent(ActivityLogin.this, MainActivity.class); 
      startActivity(intent); 
     } 

     @Override 
     public void onCancel() { 
      Log.d("TOKEN", "Canceled!!!!!!!!!!"); 

     } 

     @Override 
     public void onError(FacebookException error) { 
      Log.d("TOKEN", "CHUUUUUUJ WIELKI!!!!!!!!!!!!"); 

     } 
    }); 
} 

@Override 
public void onStart() { 
    super.onStart(); 

    OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); 
    if (opr.isDone()) { 
     // If the user's cached credentials are valid, the OptionalPendingResult will be "done" 
     // and the GoogleSignInResult will be available instantly. 
     Log.d(TAG, "Got cached sign-in"); 
     GoogleSignInResult result = opr.get(); 
     handleSignInResult(result); 
    } else { 
     // If the user has not previously signed in on this device or the sign-in has expired, 
     // this asynchronous branch will attempt to sign in the user silently. Cross-device 
     // single sign-on will occur in this branch. 
     showProgressDialog(); 
     opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { 
      @Override 
      public void onResult(GoogleSignInResult googleSignInResult) { 
       hideProgressDialog(); 
       handleSignInResult(googleSignInResult); 
      } 
     }); 
    } 
} 

// [START onActivityResult] 
@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); 
    if (requestCode == RC_SIGN_IN) { 
     GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 
     handleSignInResult(result); 
    } 
} 
// [END onActivityResult] 

// [START handleSignInResult] 
private void handleSignInResult(GoogleSignInResult result) { 
    Log.d(TAG, "handleSignInResult:" + result.isSuccess()); 
    if (result.isSuccess()) { 
     // Signed in successfully, show authenticated UI. 
     GoogleSignInAccount acct = result.getSignInAccount(); 
     //mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName())); 
     //updateUI(true); 
     Intent intent = new Intent(ActivityLogin.this, MainActivity.class); 
     startActivity(intent); 

     String idToken = acct.getIdToken(); 
     if (idToken != null) { 
      Log.d("TOKEN", idToken); 
      //sendEmail(idToken); 
     } else { 
      Log.d("TOKEN", "CHUUUUUUJ WIELKI!"); 
     } 
    } else { 
     // Signed out, show unauthenticated UI. 
     //updateUI(false); 
    } 
} 
// [END handleSignInResult] 

// [START signIn] 
private void signIn() { 
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 
    startActivityForResult(signInIntent, RC_SIGN_IN); 
} 
// [END signIn] 



@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    // An unresolvable error has occurred and Google APIs (including Sign-In) will not 
    // be available. 
    Log.d(TAG, "onConnectionFailed:" + connectionResult); 
} 

private void showProgressDialog() { 
    if (mProgressDialog == null) { 
     mProgressDialog = new ProgressDialog(this); 
     mProgressDialog.setMessage(getString(R.string.loading)); 
     mProgressDialog.setIndeterminate(true); 
    } 

    mProgressDialog.show(); 
} 

private void hideProgressDialog() { 
    if (mProgressDialog != null && mProgressDialog.isShowing()) { 
     mProgressDialog.hide(); 
    } 
} 

@Override 
public void onClick(View v) { 
    switch (v.getId()) { 
     case R.id.google_button: 
      signIn(); 
      break; 
     case R.id.tutorial: 
      Intent intent = new Intent(this, TutorialActivity.class); 
      startActivity(intent); 
      break; 
//   case R.id.disconnect_button: 
//    revokeAccess(); 
//    break; 
    } 
} 

protected void setGooglePlusButtonText(SignInButton signInButton, String buttonText) { 
    // Find the TextView that is inside of the SignInButton and set its text 
    for (int i = 0; i < signInButton.getChildCount(); i++) { 
     View v = signInButton.getChildAt(i); 

     if (v instanceof TextView) { 
      TextView tv = (TextView) v; 
      tv.setText(buttonText); 
      return; 
     } 
    } 
    } 
}       

這裏是XML佈局此類:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context=".ActivityLogin" 
android:background="@drawable/background_gradient"> 

<com.facebook.login.widget.LoginButton 
    android:id="@+id/facebook_button" 
    android:layout_width="200dp" 
    android:layout_height="40dp" 
    android:layout_above="@+id/google_button" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="20dp" /> 

<com.google.android.gms.common.SignInButton 
    android:id="@+id/google_button" 
    android:layout_width="200dp" 
    android:layout_height="40dp" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="60dp" 
    /> 

看來,我米西在這裏重要的東西,但我找不到它是什麼。第一條錯誤消息說我缺少權限,但根據谷歌和Facebook教程這個特殊的權限是不需要的。

回答

1

您沒有在您的onActivityResult()方法中處理Facebook結果。

添加到您的方法 -

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); 
    if (requestCode == RC_SIGN_IN) { 
     GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 
     handleSignInResult(result); 
    } 
    else{ 
     //Add this to handle Facebook result 
     facebookCallbackManager.onActivityResult(requestCode, resultCode, data); 
    } 
} 
+0

這是正確的答案。我不確定是否應該提出另一個問題:當成功登錄時,我想將用戶帶到另一個活動。如果我想讓他們選擇註銷,我如何確定選擇哪個驗證用戶? – Lenny

+0

您以不同方式收到Facebook和Google的回調,那麼問題是什麼?您可以將其存儲在SharedPreferences中,無論它是Google還是FB。 –