studio - Google inicia y cierra sesión en Android utilizando la última API de g-plus
android tag example (4)
He revisado algunas de las preguntas de stackoverflow relacionadas con el inicio y cierre de sesión de google plus. Y la mayoría de ellos están desactualizados. No soy capaz de lograr lo que realmente quiero.
Una vez que inicie sesión, la próxima vez que inicie sesión, deseo que el usuario elija la cuenta de Google disponible para iniciar sesión nuevamente.
Estoy usando el botón de inicio y cierre de sesión personalizado. Y para salir, tengo dos casos,
- cierre la sesión justo antes de iniciar sesión si algún usuario ya ha iniciado sesión en la misma actividad de inicio de sesión.
- Salir de la actividad diferente.
Esto es lo que he implementado hasta ahora:
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;
}
}
}
En cuanto al cierre de sesión de una actividad diferente, ninguna de las respuestas que encontré define cómo iniciar mGoogleApiClient en la nueva actividad.
Para el cierre de sesión si implemento el siguiente código:
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) {
}
});
}
}
Lanza el error.
Al eliminar la parte de cierre de sesión de la actividad de inicio de sesión, puedo iniciar sesión correctamente desde GPlus.
Gradle:
compile ''com.google.android.gms:play-services-auth:9.2.1''
compile ''com.google.android.gms:play-services:9.2.1''
NOTA: a partir de la actividad de inicio de sesión, puedo iniciar sesión desde google plus o el libro de consulta.
Actividad A (Iniciar sesión desde g + o fb).
Después de iniciar sesión, el usuario se dirige a la Actividad B, desde la Actividad B, el usuario puede cerrar sesión en el portal apropiado (g + o fb).
Parte de Facebook está hecha. Sólo queda g +.
Por favor, ayude a cerrar la sesión correctamente en ambos casos AL USAR LAS API DE REGISTRO DE REGISTRO DE GOOGLE ACTUALIZADAS.
Haga esto en su segunda actividad . Si está guardando alguna preferencia con respecto al inicio de sesión en la primera actividad, bórrelo al hacer clic en cerrar sesión
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();
}
}
}
Una vez que inicie sesión, la próxima vez que inicie sesión, deseo que el usuario elija la cuenta de Google disponible para iniciar sesión nuevamente.
El truco consiste en borrarDefaultAccountAndReconnect el GoogleApiClient justo después de que el usuario haga clic en el botón Iniciar sesión en Google para iniciar sesión. Esto garantiza que todas las cuentas de Google disponibles se muestren siempre que haga clic en el botón Iniciar sesión.
PASO 1: Inicialice GoogleAPIClient y configure onClickListener en googleSignInButton en 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);
}
PASO 2: Maneje el inicio de sesión de Google a través de su método 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;
}
}
Misceláneo
// 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();
}
}
}
¿Por qué necesitas tantos métodos de devolución de llamada en tu código? Supongo que complicaste un poco tu código. El truco principal es desconectar y borrar la cuenta predeterminada cuando el usuario intenta iniciar sesión, lo que garantiza que siempre se le muestre una lista de cuentas de Google válidas. He utilizado el mismo procedimiento, se ha probado, probado y ha funcionado.
Solo un método de devolución de llamada para el estado de inicio de sesión utilizado en mi aplicación.
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);
}
Una vez que inicie sesión, la próxima vez que inicie sesión, deseo que el usuario elija la cuenta de Google disponible para iniciar sesión nuevamente.
Simplemente, cierre la sesión del usuario y revoque el acceso cuando el usuario haga clic en el botón de cerrar sesión. La próxima vez, cuando los usuarios intenten iniciar sesión, se le pedirá que elija su cuenta de Google preferida.
Como está iniciando sesión y desconectándose de diferentes actividades, está terminando con un código duplicado. En lugar de duplicar el código, simplemente use una clase auxiliar e inicialice la Opción de inicio de sesión de Google y el Cliente API de Google. Ahora, siempre que desee utilizar el cliente API de Google, puede inicializar la clase auxiliar.
Caso 1. Si desea cerrar sesión antes de iniciar sesión, use clearDefaultAccountAndReconnect
.
Caso 2. Para Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback
del usuario (no importa lo que sea la actividad), use Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback
.
Aquí está el enlace github al proyecto. Puedes echar un vistazo si aún tienes dudas.
Para cerrar sesión puede utilizar el siguiente método:
private void signOut() {
Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
Timber.d("Logged out");
}
});
}
Para iniciar sesión puedes seguir estos métodos:
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);
}