Google 使用 g-plus 最新 API 在 android 中登录和注销

Posted

技术标签:

【中文标题】Google 使用 g-plus 最新 API 在 android 中登录和注销【英文标题】:Google sign in and sign out in android using g-plus latest API 【发布时间】:2016-12-12 16:28:21 【问题描述】:

我已经完成了一些与登录和退出 google plus 相关的 *** 问题。而且它们中的大多数已经过时了。我无法实现我真正想要的。

退出后,下次登录时,我希望用户选择可用的 Google 帐户再次登录。

我正在使用自定义登录和退出按钮。而对于退出,我有两种情况,

    如果任何用户已在同一登录活动中登录,请在登录前退出。 退出不同的活动。

这是我目前已经实现的:

public class LoginActivity extends AppCompatActivity implements OnClickListener

    private static final int RC_SIGN_IN = 9001;
    private GoogleApiClient mGoogleApiClient;
    private ConnectionResult mGoogleConnectionResult;
    private Button login;
    private ProgressDialog mProgressDialog;
    private Context mContext;
    private String mUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        mContext= LoginActivity.this;
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.login_layout);

        login= (Button) findViewById(R.id.lg_login_btn);
        login.setOnClickListener(this);
    

    @Override
    public void onClick(View v) 
        if(isOnline(mContext))
            if(v.getId()== R.id.lg_login_btn) 
                if(mGoogleApiClient!=null)
                    mGoogleApiClient.disconnect();
                
            GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(new Scope(Scopes.PLUS_LOGIN))
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(mContext.getApplicationContext())
            .enableAutoManage(this , mGPlusConnectionFailedListener)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .addApi(Plus.API)
            .build();

        signOutGPlus();
        Intent lSignInIntent= Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(lSignInIntent, RC_SIGN_IN);

            
         else
            showAlertDialog(mContext, "Error", "Please check internet connection");
        
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        logD("&&onActivityResult", "requestCode: "+requestCode);     // first

        if (requestCode == RC_SIGN_IN) 
            if(resultCode == RESULT_OK)
                showProgressDialog();
                getGPlusUserInfo(data);
             else 
                logD("&&onActivityResult", "requestCode: RESULT_ NOT Ok"+requestCode);
            
        
    

    GoogleApiClient.OnConnectionFailedListener mGPlusConnectionFailedListener= new GoogleApiClient.OnConnectionFailedListener() 
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 
            logD("&&mGPlusConnectionFailedListener", "onConnectionFailed");
        
    ;

    private void getGPlusUserInfo(Intent data)
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
    

    private void handleSignInResult(GoogleSignInResult result) 
        Log.d("&&handleSignInResult", "handleSignInResult:" + result.isSuccess());
        if (result.isSuccess()) 
            // Signed in successfully, show authenticated UI.
            String lDisplayName="";
            String lEmail="";
            String lFirstName="";
            String lLastName="";
            String lGender="";

            // G+
            if (mGoogleApiClient.hasConnectedApi(Plus.API)) 
                logD("&&GPlusUserInfo", "&hasConnectedApi--------------------------------");
                // Deprecated
                Person person = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
                if(null != person) 
                    logD("&&GPlusUserInfo", "&--------------------------------");
                    logD("&&GPlusUserInfo", "&Display Name: " + person.getDisplayName());
                lDisplayName= person.getDisplayName();
                    logD("&&GPlusUserInfo", "Gender: " + person.getGender());
                    if(person.getGender()< MyHalConstants.GENDER.length)
                        lGender= MyHalConstants.GENDER[person.getGender()];
                     else
                        lGender= "Other";
                    
                
            
            GoogleSignInAccount acct = result.getSignInAccount();

            if(null != acct) 
                if (null != acct.getDisplayName()) 
                    logD("&&GPlusUserInfo", "&Display Name: " + acct.getDisplayName());
                
                lFirstName= acct.getGivenName();
                lLastName= acct.getFamilyName();
                // Views inside NavigationView's header
                Uri uri = acct.getPhotoUrl();                  
            
         else 
            // Signed out, show unauthenticated UI.
            signOutGPlus();
        
    


    // sign - out 
    private void signOutGPlus()
        logD("&&signOutGPlus", "signOutGPlus");
        if(null != mGoogleApiClient)
            mGoogleApiClient.connect();
            mGoogleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() 

                @Override
                public void onConnected(@Nullable Bundle bundle) 
                    if(mGoogleApiClient.isConnected()) 
                        logD("&&signOutGPlus", "inside");
                    Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                            new ResultCallback<Status>() 
                                    @Override
                                    public void onResult(@NonNull Status status) 
                                        logD("&&signOutGPlus", "onResult");
                                        if(mGoogleApiClient.isConnected())
                                        mGoogleApiClient.clearDefaultAccountAndReconnect();
                                            mGoogleApiClient.disconnect();
                                    
                                    // Deprecated
                                    /*Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
                                    //Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient);
                                    //revokeAccess();*/
                                    
                                
                    );
                    
                

                @Override
                public void onConnectionSuspended(int i) 

                
            );
        
    

// Not used
    private void revokeAccess() 
    logD("&&revokeAccess", "revokeAccess");
    Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
            new ResultCallback<Status>() 
                    @Override
                    public void onResult(Status status) 
                        // ...
                    
                );
    

    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();
        
    

    private void showAlertDialog(Context pContext, String pTitle, String pMessage)
        AlertDialog.Builder ldialogBuilder= new AlertDialog.Builder(pContext);
        ldialogBuilder.setTitle(pTitle)
            .setMessage(pMessage)
        .setPositiveButton("Ok", null);
        ldialogBuilder.show();
    

    private void dismissDialog()
        if(null != mProgressDialog)
            mProgressDialog.dismiss();
            mProgressDialog= null;
        
    

关于从不同活动中退出,我遇到的答案都没有定义如何在新活动中初始化 mGoogleApiClient

如果我实现以下代码,则用于注销:

private GoogleApiClient mGoogleApiClient;

// sign - out 
private void signOutGPlusFromDifferentActivity()
    logD("&&signOutGPlus", "signOutGPlus");
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(new Scope(Scopes.PLUS_LOGIN))
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(mContext.getApplicationContext())
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .addApi(Plus.API)
            .build();
    if(null != mGoogleApiClient)
        mGoogleApiClient.connect();
        mGoogleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() 
            @Override
            public void onConnected(@Nullable Bundle bundle) 
                if(mGoogleApiClient.isConnected()) 
                    logD("&&signOutGPlus", "inside");
                    Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                            new ResultCallback<Status>() 
                                @Override
                                public void onResult(@NonNull Status status) 
                                    logD("&&signOutGPlus", "onResult");
                                    if(mGoogleApiClient.isConnected())
                                        mGoogleApiClient.clearDefaultAccountAndReconnect();
                                        mGoogleApiClient.disconnect();
                                    
                                
                            
                    );
                
            
            @Override
            public void onConnectionSuspended(int i) 

            
        );
    

它会抛出错误。

通过从登录活动中删除退出部分,我可以从 GPlus 正确登录。

分级:

compile 'com.google.android.gms:play-services-auth:9.2.1'
compile 'com.google.android.gms:play-services:9.2.1'

注意:通过登录活动,我可以从 google plus 或 Facebook 登录。

活动 A(从 g+ 或 fb 登录)。

登录后,用户被定向到活动 B,从活动 B 用户可以从相应的门户(g+ 或 fb)注销。

Facebook 部分已完成。只剩下g+了。

请通过使用更新的 GOOGLE LOGIN LOGOUT API 帮助在这两种情况下正确退出。

【问题讨论】:

你可以用它来登录 google+ [learn2crack.com/2013/12/android-google-plus-api-example.html] .对于注销,您可以使用此代码@Override public void onClick(View view) if (view.getId() == R.id.sign_out_button) if (mGoogleApiClient.isConnected()) Plus.AccountApi.clearDefaultAccount(mGoogleApiClient); mGoogleApiClient.disconnect(); mGoogleApiClient.connect(); @One Punch Man,我已经为您的问题添加了一个可行的解决方案。几天前我遇到了同样的问题。这个解决方案肯定会奏效。如果有帮助,请尝试解决方案并接受答案:) :) 能否请您详细说明问题。 同时发布您的错误日志。 【参考方案1】:

在您的第二个活动中执行此操作。如果您要保存任何首选项 关于登录第一个活动然后在注销点击

上清除它
package com.ccc.bbbb;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.plus.People;
import com.google.android.gms.plus.People.LoadPeopleResult;
import com.google.android.gms.plus.Plus;



//implement ConnectionCallbacks, OnConnectionFailedListener,ResultCallback<People.LoadPeopleResult> 

public class HomeActivity extends Activity implements OnClickListener ,ConnectionCallbacks, OnConnectionFailedListener,
ResultCallback<People.LoadPeopleResult> 


    public static boolean isLogout=false;
    GoogleApiClient mGoogleApiClient;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this).addApi(Plus.API)
        .addScope(Plus.SCOPE_PLUS_LOGIN).build();

            //Logout button click


                    if(networkCheck.isNetworkAvailable(HomeActivity.this))
                    
                        Log.d(TAG, "logout if condition working....");  


                            isLogout=true;

                            if(mGoogleApiClient.isConnected())
                            
                                Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
                                mGoogleApiClient.disconnect();
                                mGoogleApiClient.connect();
                            
                            Toast.makeText(HomeActivity.this, "you are logged out", Toast.LENGTH_SHORT).show();

                            Intent intent=new Intent(HomeActivity.this,MainActivity.class);
                            startActivity(intent);
                            finish();

                        



//override below methods and copy those codes

        @Override
         public void onResult(@NonNull LoadPeopleResult arg0) 
            // TODO Auto-generated method stub

         


         @Override
         public void onConnectionFailed(@NonNull ConnectionResult arg0) 
            // TODO Auto-generated method stub

         


         @Override
         public void onConnected(@Nullable Bundle arg0) 
            // TODO Auto-generated method stub
            mSignInClicked = false;

             // updateUI(true);
             Plus.PeopleApi.loadVisible(mGoogleApiClient, null).setResultCallback(
                     this);

         


         @Override
         public void onConnectionSuspended(int arg0) 
            // TODO Auto-generated method stub
            mGoogleApiClient.connect();

         

         @Override
         protected void onStart() 
            // TODO Auto-generated method stub
            super.onStart();
            mGoogleApiClient.connect();

         
         @Override
         protected void onStop() 
         
            // TODO Auto-generated method stub
            super.onStop();
            if (mGoogleApiClient.isConnected()) 
                 mGoogleApiClient.disconnect();
             
            if (mDialog.isShowing()) 
                mDialog.dismiss();
            

         





【讨论】:

【参考方案2】:

退出后,下次登录时,我希望用户选择可用的 Google 帐户再次登录。

诀窍是在用户单击 Google 登录按钮登录后立即clearDefaultAccountAndReconnect GoogleApiClient这可确保在您点击登录按钮时始终显示所有可用的 Google 帐户。

第 1 步:初始化 GoogleAPIClient 并将 onClickListener 设置为 Activity onCreate() 中的 googleSignInButton

private GoogleApiClient mApiClient;

private void initializeGoogleSignIn() 
    GoogleSignInOptions signInOptions = new GoogleSignInOptions
            .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestProfile()
            .build();

    mApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, signInOptions)
            .build();

    SignInButton googleSignInButton = (SignInButton) findViewById(R.id.google_sign_in);

    googleSignInButton.setOnClickListener(this);

第 2 步:通过 onClick() 方法处理 Google 登录

@Override
public void onClick(View v) 

    switch (v.getId()) 
        case R.id.google_sign_in:

            if (mApiClient.isConnected()) 
                mApiClient.clearDefaultAccountAndReconnect();
             else 
                mApiClient.connect();
            

            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mApiClient);
            startActivityForResult(signInIntent, RC_SIGN_IN);

            break;
    

杂项

// Make sure you connect and disconnect the GoogleApiClient in onStart and onStop lifecycle methods
@Override
protected void onStart() 
    super.onStart();
    mApiClient.connect();


@Override
protected void onStop() 
    super.onStop();
    if (mApiClient.isConnected())
        mApiClient.disconnect();




 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) 
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);

            if (result != null && result.isSuccess()) 

                GoogleSignInAccount account = result.getSignInAccount();

                setAppPreferenceData(account.getId(), account.getEmail(), String.valueOf(account.getPhotoUrl()), account.getDisplayName());

                startActivity(new Intent(this, NavigationActivity.class));


                finish();
             else 
                mProgressLayout.setVisibility(View.GONE);

                if (Utils.isNetworkAvailable(this))
                    Toast.makeText(this, "Google Authentication Failed! Please try again", Toast.LENGTH_SHORT).show();
                else
                    Toast.makeText(this, "Network Error! Please connect to your wifi.", Toast.LENGTH_LONG).show();
            
         
    

为什么你的代码中需要这么多回调方法?我想你的代码有点复杂。 主要技巧是在用户尝试登录时断开连接并清除默认帐户,以确保始终显示有效的 Google 帐户列表。 我使用了相同的程序,它已经过尝试、测试和工作。

我的应用中使用的登录状态只有一种回调方法。

public class SignInActivity extends AppCompatActivity implements
        GoogleApiClient.OnConnectionFailedListener 


@Override
public void onConnectionFailed(ConnectionResult connectionResult) 
    Toast.makeText(SignInActivity.this, "Google Play connection error", Toast.LENGTH_SHORT).show();
    mProgressLayout.setVisibility(View.GONE);

【讨论】:

它永远不会进入 isconnected 条件。从不同的活动登录怎么样?如何在不同的退出活动中定义 mApiClient。 @OnePunchMan,退出其他活动非常具有挑战性。您可以尝试制作 GoogleApiClient 单例,以便在整个应用程序中都可以访问它。但是,在像您一样遇到类似情况后,我发现最好的做法是在用户即将再次登录之前注销并清除他的帐户。我将在答案的 MISC 部分下发布更多代码。 我之前已经尝试过您编写的代码示例。它永远不会进入 if(mApiClient.isConnected()) .【参考方案3】:

注销可以使用以下方法:

private void signOut() 
    Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(
            new ResultCallback<Status>() 
                @Override
                public void onResult(Status status) 
                    Timber.d("Logged out");
                
            );

您可以按照以下方法登录:

public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) 
    this.activity = activity;
    if (requestCode == RC_SIGN_IN) 
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
    

   /*For inintializing googleapiclient*/
    private void initGoogleClient() 

    gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

    googleApiClient = new GoogleApiClient.Builder(activity)
            .enableAutoManage((FragmentActivity) activity /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API)
            .addScope(new Scope(Scopes.PROFILE))
            .build();


private void signIn() 
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
    activity.startActivityForResult(signInIntent, RC_SIGN_IN);

【讨论】:

【参考方案4】:

退出后,下次登录时,我希望用户选择可用的 Google 帐户再次登录。

只要用户点击退出按钮,只需退出用户并撤销访问权限。下次,当用户尝试登录时,系统会要求他/她选择他们喜欢的 Google 帐户。

由于您正在登录和退出不同的活动,因此您最终会得到重复的代码。无需复制代码,只需使用帮助类并初始化 Google SignIn Option 和 Google API Client。现在,每当您想使用 Google API 客户端时,您都可以初始化帮助程序类。

案例1。如果您想在登录前退出,请使用clearDefaultAccountAndReconnect

案例 2。 对于退出用户(无论活动是什么),请使用 Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback

这是项目的github link。有疑问的可以看一下。

【讨论】:

【参考方案5】:

这解决了我的问题:-

Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
            new ResultCallback<Status>() 
                @Override
                public void onResult(@NonNull Status status) 
                    Toast.makeText(context, "Success"+status.getStatusMessage(), Toast.LENGTH_SHORT).show();
                
            );

【讨论】:

以上是关于Google 使用 g-plus 最新 API 在 android 中登录和注销的主要内容,如果未能解决你的问题,请参考以下文章

如何在现有的旧版Android项目中使用最新的API添加Google Map?

更新服务器端计费确认 API 需要 Google Play 控制台操作,但 API 已在使用最新版本

最新的 Google Adwords oAuth API 实施

使用 Google Play 服务我可以在离线模式下获取最新位置吗(FusedLocationProvider Api)

有人可以为 Google Drive REST API v3 提供最新的 Android 指南吗?

在 Python 中获取 google 电子表格 api v4 中的工作表和最新工作表列表