Вход и выход из Google на Android с использованием новейшего API g-plus

Я рассмотрел некоторые вопросы, касающиеся stackoverflow, связанные со входом и выходом из Google Plus. И большинство из них устарели. Я не могу добиться того, чего действительно хочу.

После выхода из системы при следующем входе пользователь должен выбрать доступную учетную запись Google для повторного входа.

Я использую настраиваемую кнопку входа и выхода. Что касается выхода, у меня есть два случая:

  1. выход непосредственно перед входом, если какой-либо пользователь уже вошел в систему в том же действии входа.
  2. выход из другой деятельности.

Вот что я реализовал до сих пор:

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+.

Пожалуйста, помогите правильно выйти из системы в обоих случаях, ИСПОЛЬЗУЯ ОБНОВЛЕННЫЕ API GOOGLE LOGIN LOGOUT.


person OnePunchMan    schedule 06.08.2016    source источник
comment
Вы можете использовать это для входа в 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(); } } }   -  person Aparajita Sinha    schedule 18.08.2016
comment
@ One Punch Man, я добавил рабочее решение твоей проблемы. Я столкнулся с той же проблемой несколько дней назад. Это решение точно сработает. Пожалуйста, попробуйте решение и примите ответ, если он поможет :) :)   -  person Adithya Upadhya    schedule 20.08.2016
comment
Не могли бы вы уточнить проблему немного подробнее.   -  person Pravin Divraniya    schedule 06.10.2016
comment
Также опубликуйте свой журнал ошибок.   -  person Pravin Divraniya    schedule 06.10.2016


Ответы (5)


Сделайте это в своем втором действии. Если вы сохраняете какие-либо настройки относительно входа в первое действие, удалите их при нажатии выхода.

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

         }




}
person Rishikesh pathak    schedule 16.08.2016

После выхода из системы при следующем входе пользователь должен выбрать доступную учетную запись Google для повторного входа.

Хитрость заключается в том, чтобы clearDefaultAccountAndReconnect GoogleApiClient сразу после того, как пользователь нажмет кнопку Google Sign in для входа. Это гарантирует, что все доступные учетные записи Google всегда будут отображаться всякий раз, когда вы нажимаете кнопку входа.

ШАГ 1. Инициализируйте GoogleAPIClient и установите для onClickListener значение googleSignInButton в Activity onCreate()

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. Обработайте вход в Google с помощью метода onClick()

@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);
}
person Adithya Upadhya    schedule 20.08.2016
comment
Он никогда не входит в состояние подключения. Как насчет входа в систему из другого действия и как вы определяете mApiClient в другом действии выхода. - person OnePunchMan; 20.08.2016
comment
@OnePunchMan, выйти из другой активности довольно сложно. Что вы можете попробовать, так это сделать GoogleApiClient Singleton так, чтобы он был доступен во всем приложении. Однако, столкнувшись с похожей ситуацией, как и вы, я решил, что лучше всего выйти из системы и очистить ее учетную запись непосредственно перед тем, как он собирается снова войти в систему. Я опубликую дополнительный код в разделе MISC моего ответа. - person Adithya Upadhya; 20.08.2016
comment
Я уже пробовал ранее пример кода, который вы написали. Он никогда не входит внутрь if(mApiClient.isConnected()) . - person OnePunchMan; 20.08.2016

Для выхода вы можете использовать следующий метод:

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);
}
person iamdeowanshi    schedule 10.10.2016

После выхода из системы при следующем входе пользователь должен выбрать доступную учетную запись Google для повторного входа.

Просто выйдите из системы и отмените доступ всякий раз, когда пользователь нажимает кнопку выхода. В следующий раз, когда пользователи попытаются войти в систему, им будет предложено выбрать предпочтительную учетную запись Google.

Поскольку вы входите и выходите из разных действий, вы получаете дублирующийся код. Вместо дублирования кода просто используйте вспомогательный класс и инициализируйте параметр Google SignIn и клиент Google API. Теперь всякий раз, когда вы хотите использовать клиент Google API, вы можете инициализировать вспомогательный класс.

Вариант 1. Если вы хотите выйти перед входом, используйте clearDefaultAccountAndReconnect.

Случай 2. Для выхода пользователя из системы (независимо от его активности) используйте Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback.

Вот ссылка github на проект. Вы можете взглянуть, если у вас все еще есть сомнения.

person Srikar Reddy    schedule 03.10.2016

Это решило мою проблему: -

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();
                }
            });
person Venkatesh    schedule 11.11.2019