Inicio Android Integración con Google+ (I): Google+ Sign-In

Integración con Google+ (I): Google+ Sign-In

por sgoliver

[box style=»full» type=»note»]ATENCIÓN: ARTÍCULO OBSOLETO

Puedes consultar información actualizada en el nuevo artículo sobre Google Sign-In.[/box]

En los próximos artículos del Curso de Programación Android vamos a centrarnos en otra de las novedades presentadas hace poco como parte de los Google Play Services, en concreto la integración de aplicaciones con Google+. Integrar nuestras aplicaciones con Google+ nos va a permitir entre otras cosas la posibilidad de que los usuarios inicien sesión en nuestra aplicación con su cuenta de Google, personalizar la aplicación en función de los datos de su perfil público y sus círculos, o enviar publicaciones a su perfil informando de la actividad del usuario en nuestra aplicación. En este primer artículo nos centraremos en la primera y más importante de estas posibilidades, el inicio de sesión con Google+.

Al igual que ocurría con las apis de mapas o mensajería push, para hacer uso de la API de integración con Google+ necesitaremos crear un nuevo proyecto en la consola de APIs de Google, habilitar el servicio de Google+, y generar una nueva «clave de acceso», en este caso un nuevo ID de Cliente para autenticación mediante OAuth 2.0.

Para ello accederemos a la Consola de APIs y crearemos un nuevo proyecto con el nombre que deseemos utilizando la opción «Create…» de la lista desplegable situada en la parte superior izquierda. Una vez creado el proyecto, accederemos a la sección «Services» y habilitaremos el servicio llamado «Google+ API».

enable-service

Tras esto, accederemos a la sección «API Access» para generar el ID de acceso al servicio. Para ello pulsamos sobre la opción «Create an OAuth 2.0 Client ID», lo que nos llevará a un asistente de configuración. En la primera pantalla indicaremos el nombre de la aplicación y un logo (opcional).

create-client-id-2_

En la segunda, seleccionaremos la opción «Installed application» y «Android» como tipo de aplicación. Además tendremos que rellenar el paquete java que utilizado en nuestra aplicación y la huella SHA1 del certificado con el que firmaremos la aplicación. Esto ya lo hemos comentado en alguna ocasión, mientras estemos desarrollando/depurando la aplicación usaremos el certificado de pruebas (debug) instalado con el SDK de Android, pero cuando subamos nuestra aplicación a Google Play tendremos que modificar este dato por el correspondiente al certificado real con el que firmemos la aplicación final (si no lo hacemos así la aplicación no funcionará). Si utilizamos una versión reciente de Eclipse y el plugin de Android (ADT) podemos obtener la huella SHA1 del certificado de pruebas accediendo a las preferencias de Eclipse, en la sección Android / Build. En la siguiente captura podéis ver la localización de este dato:

create-client-id-3-bis

Si no dispusiéramos de una versión reciente de las herramientas de desarrollo, también podemos obtener el dato utilizando la utilidad keytool de java, tal como se indica por ejemplo en el artículo del curso sobre la API de Google Maps.

Por último, activaremos la opción «Deep Linking Enabled» y finalizaremos el asistente pulsando el botón «Create client ID».

create-client-id-3_

Con esto ya tendríamos configurado el proyecto en la Consola de APIs y podríamos comenzar a crear el proyecto en Eclipse. El primer paso, como ocurre con todos los proyectos que hacen uso de los Google Play Services, será importar el proyecto de librería que lo soporta y hacer referencia a él desde nuestro proyecto. Estos pasos se comentan en detalle en el artículo de introducción a los Google Play Services.

Una vez preparado el proyecto en Eclipse entramos por fin en la parte interesante. Para añadir el botón de login de Google+ en nuestra aplicación bastará con incluir en nuestro layout un control de tipo SignInButton de la siguiente forma:

<com.google.android.gms.common.SignInButton
    android:id="@+id/sign_in_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Este botón será el que permita al usuario acceder a nuestra aplicación haciendo uso de su usuario de Google. Sin embargo, no será el botón el que desencadene el proceso de conexión a Google+, sino que actuaremos de una forma algo peculiar. Nuestra actividad intentará conectarse al servicio desde su inicio de forma que si el usuario ya estaba logueado con anterioridad el proceso de conexión se transparente para él. De forma análoga, justo al salir de la actividad nos desconectaremos del servicio.

Pero entonces, ¿para qué nos sirve el botón de login? Pues la clave del párrafo anterior está en las palabras «si el usuario ya estaba logueado con anterioridad«. Y no sólo eso, para que la conexión sea completamente transparente y no necesite ninguna intervención del usuario, éste debe estar ya logueado y además debe haber dado su permiso para que la aplicación acceda a sus datos de Google+ y pueda realizar determinadas acciones en su nombre. En el caso de que alguno de estos pasos no se hayan realizado ya, el intento de conexión realizado al inicio de la actividad derivará en un «error» que deberá ser tratado por el usuario. Y esto es precisamente lo que conseguirá el usuario al pulsar el botón de login colocado en la aplicación. Pero tampoco hay que preocuparse, porque la API de Google+ proporciona todos los elementos necesarios para que el usuario pueda resolver estas acciones, por ejemplo el diálogo de selección de la cuenta con la que se accederá a Google+, o el diálogo donde el usuario podrá seleccionar los permisos relacionados con Google+ que desea conceder a la aplicación (por ejemplo, la visibilidad de determinados círculos).

Pues bien, veamos cómo plasmamos en el código de la aplicación todo esto que hemos contado con palabras. Empezaremos inicializando los componentes necesarios durante la creación de la actividad. La conexión con Google+ se sustenta completamente en la clase PlusClient, por lo que el primer paso será crear e inicilizar un objeto de este tipo. Esto lo conseguimos mediante el método PlusClient.Builder(). En esta inicialización indicaremos además las actividades (de «acciones», no de «Activity») del usuario en la aplicación que la propia aplicación podrá publicar en el perfil de Google+ en nombre del usuario (por ejemplo acciones del estilo a «He escuchado tal canción», «He visto tal imagen» o «He comentado tal noticia»). Existen varios tipos de actividad predefinidas como BuyActivity, ListenActivity, CommentActivity para actividades de compras, reproducción de música o comentarios (podéis revisar la lista completa en esta página y un tipo genérico (AddActivity) para cuando las actividades que enviará nuestra aplicación a Google+ con encaja con ninguno de los tipos predefinidos. La lista de actividades que la aplicación podrá enviar al perfil de Google+ del usuario se configurará mediante el método setVisibleActivities(), y serán mostradas al usuario al loguearse por primera vez en la aplicación de forma que éste sea consciente de ello y pueda conceder su permiso. Más tarde pondré una captura de pantalla donde podrá verse esto claramente. En nuestro caso añadiremos por ejemplo las actividades AddActivity y ListenActivity para ver el efecto. Además de esto, para terminar inicializaremos también un diálogo de progreso que utilizaremos más tarde. Veamos cómo queda el método onCreate() al completo:

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

	btnSignIn = (SignInButton)findViewById(R.id.sign_in_button);

	plusClient = new PlusClient.Builder(this, this, this)
		.setVisibleActivities(
			"http://schemas.google.com/AddActivity",
			"http://schemas.google.com/ListenActivity")
		.build();

	connectionProgressDialog = new ProgressDialog(this);
	connectionProgressDialog.setMessage("Conectando...");

	//...
}

Vamos ahora con la conexión y desconexión a Google+. Como dijimos anteriormente, la conexión la intentaremos realizar desde el inicio de la actividad y nos desconectaremos juasto al salir, por lo que podemos aprovechar los eventos onStart() y onStop() de la actividad para realizar estas acciones. Utilizaremos para ello los métodos connect() y disconnect() de la clase PlusClient.

@Override
protected void onStart()
{
	super.onStart();
	plusClient.connect();
}

@Override
protected void onStop()
{
	super.onStop();
	plusClient.disconnect();
}

Para capturar el resultado de estas acciones de conexión y desconexión podemos implementar los eventos onConnected() y onDisconnected(), para lo que nuestra actividad tendrá que implementar la interfaz ConnectionCallbacks.

public class MainActivity extends Activity
	implements ConnectionCallbacks
{
	//...

	@Override
	public void onConnected(Bundle connectionHint)
	{
		connectionProgressDialog.dismiss();

		Toast.makeText(this, "Conectado!",
			Toast.LENGTH_LONG).show();
	}

	@Override
	public void onDisconnected()
	{
		Toast.makeText(this, "Desconectado!",
			Toast.LENGTH_LONG).show();
	}
}

Con lo implementado hasta ahora bastará la mayoría de las veces. Sin embargo, como dijimos al principio, la primera vez que el usuario se intenta conectar se requieren acciones adicionales, como seleccionar la cuenta a utilizar con Google+ o conceder a la aplicación los permisos necesarios para interactuar con nuestro perfil de Google+. En estas circunstancias la llamada al método connect() no tendrá éxito. ¿Cómo podemos solucionarlo? Pues como ya hemos indicado esta situación intentará solucionarse cuando el usuario pulse el botón de login de Google+ que hemos colocado en la aplicación. Pero para poder solucionarlo antes debemos saber qué ha ocurrido exactamente en la llamada a connect(). Esto lo podemos saber implementando el evento onConnectionFailed() que se ejecuta cuando la llamada a connect() no finaliza correctamente. Este evento recibe como parámetro un objeto de tipo ConnectionResult que contiene el motivo por el que no hemos podido conectarnos al servicio de Google+. Para poder gestionar este evento haremos que nuestra actividad implemente otra interfaz más llamada OnConnectionFailedListener.

public class MainActivity extends Activity
	implements ConnectionCallbacks, OnConnectionFailedListener
{
	//...

	@Override
	public void onConnectionFailed(ConnectionResult result)
	{
		//...

		connectionResult = result;
	}
}

Como podemos ver, en este evento nos limitaremos por el momento a guardar el objeto ConnectionResult para tenerlo disponible cuando el usuario pulse el botón de login.

Y vamos ya por fin con nuestro botón. ¿Qué debemos hacer cuando el usuario pulse el botón de login? Pues en primer lugar comprobaremos que no estamos ya conectados mediante una llamada al método isConnected(), en cuyo caso no habrá nada que hacer. Si no estamos aún conectados pueden ocurrir dos cosas: que dispongamos ya del resultado del intento de conexión en forma de objeto ConnectionResult, o que aún no lo tengamos disponible. Para este último caso utilizaremos el diálogo de progreso que inicializamos en el onCreate() de la actividad, lo mostraremos mediante su método show() y quedaremos a la espera de disponer del resultado de la conexión.

En caso de conocer ya el resultado de la conexión, llamaremos a su método startResolutionForResult(). Este método «mágico» provocará que se muestren al usuario las opciones necesarias para resolver los «errores» detectados durante el intento de conexión a Google+, entre ellos la selección de cuenta o el diálogo de concesión de permisos de Google+.

btnSignIn.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View view)
	{
		if (!plusClient.isConnected())
		{
			if (connectionResult == null)
			{
				connectionProgressDialog.show();
			}
			else
			{
				try
				{
					connectionResult.startResolutionForResult(
						MainActivity.this,
						REQUEST_CODE_RESOLVE_ERR);
				}
				catch (SendIntentException e)
				{
					connectionResult = null;
					plusClient.connect();
				}
			}
		}
	}
});

Cuando el usuario termine de configurar las opciones de conexión a Google+ se lanzará automáticamente el evento onActivityResult(), momento que aprovecharemos para volver a realizar la conexión llamando de nuevo a connect() ahora que no deberían quedar acciones por realizar por parte el usuario. Si todo va bien, este nuevo intento de conexión debería terminar con éxito y el usuario quedaría conectado (y entre otras cosas se ejecutará el evento onConnected() del que ya hemos hablado).

@Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent)
{
	if (requestCode == REQUEST_CODE_RESOLVE_ERR &&
	    responseCode == RESULT_OK)
	{
		connectionResult = null;
		plusClient.connect();
	}
}

Con esto casi hemos terminado. Pero nos faltan un par de detalles por cerrar que antes he omitido a posta para llevar un orden más lógico en la explicación. En primer lugar, ¿qué ocurre cuando el resultado del primer intento de conexión nos llega después de que el usuario haya pulsado el botón de login (y por tanto ya se está mostrando el diálogo de progreso)? En ese caso no sólo guardaremos el resultado de la conexión, sino que desencadenaremos directamente el proceso de resolución de errores llamando a startResolutionForResult() igual que hemos hecho en el evento onClick del botón de login. De esta forma, el evento onConnectionFailed() quedaría finalmente de la siguiente forma:

@Override
public void onConnectionFailed(ConnectionResult result)
{
	if (connectionProgressDialog.isShowing())
	{
		if (result.hasResolution())
		{
			try
			{
				result.startResolutionForResult(this,
					REQUEST_CODE_RESOLVE_ERR);
			}
			catch (SendIntentException e)
			{
				plusClient.connect();
			}
		}
	}

	connectionResult = result;
}

Por útlimo, nos queda cerrar el diálogo de progreso una vez que el usuario esté correctamente conectado, lo que haremos en el evento onConnected() y utilizaremos para ello el método dismiss() del diálogo, quedando finalmente así:

@Override
public void onConnected(Bundle connectionHint)
{
	connectionProgressDialog.dismiss();

	Toast.makeText(this, "Conectado!",
		Toast.LENGTH_LONG).show();
}

Y ahora sí habríamos terminado, por lo que estamos en condiciones de probar la aplicación. Recomiendo probar en un dispositivo real conectado por USB, ya que los servicios de Google Play no funcionan correctamente en el emulador (dependiendo de la versión e imagen de Android utilizada).

Al ejecutar la aplicación se mostrará el botón de login de Google+ y comenzará de forma silenciosa el proceso de conexión.

demo-1

Al pulsar el botón de Iniciar Sesión debemos ya contar con el resultado de la conexión, por lo que se nos debe dirigir directamente al proceso de resolución de errores. En primer lugar tendremos que seleccionar la cuenta de google con la que queremos contectarnos:

demo-2

Tras seleccionar una cuenta aparecerá el diálogo de configuración de permisos de Google+, en el que se informa al usuario de los permisos que solicita la aplicación. Podremos definir los círculos a los que tendrá acceso la aplicación y los círculos que podrán ver las publicaciones que la aplicación realice por nosotros en nuestro perfil de Google+.

demo-4

En la captura anterior me gustaría que prestárais atención al texto del segundo bloque, donde indica «Permitir que la actividad de aplicaciones y de audio esté disponible…». Este mensaje debe coincidir con las actividades que establecimos al llamar al método setVisibleActivities() al principio del ejemplo. Recuerdo que nosostros seleccionamos la genérica AddActivity y la de audio ListenActivity.

Tras aceptar esta última pantalla deberíamos estar ya conectados correctamente a Google+, apareciendo el mensaje toast que nos informa de ello. Lo que podremos hacer a partir de aquí queda para el siguiente artículo.

Pero no terminamos aún, nos quedan un par de temas importantes por añadir. Si queremos que nuestra aplicación cumpla con las políticas de Google+ debemos ofrecer al usuario una opción para cerrar sesión en Google+, y otra para que pueda revocar los permisos que ha concedido a nuestra aplicación la primera vez que se conectó.

En mi ejemplo añadiré estas opciones como acciones del menú de overflow de la action bar (si necesitas información sobre cómo hacer esto puedes ojear el artículo sobre la action bar).

Cerrar sesión será tan sencillo como llamar al método clearDefaultAccount() y desconectarnos con disconnect(). Posteriormente volvemos a llamar a connect() para que se inicie un nuevo proceso de login si el usuario pulse de nuevo el botón.

La opción de revocar los permisos de la aplicación tampoco es mucho más complicada. Llamaremos igual que antes al método clearDefaultAccount() para eliminar la vinculación de nuestra cuenta con la aplicación, y posteriormente llamaremos a revokeAccessAndDisconnect() para revocar los permisos concedidos. Este último método recibe como parámetro el listener con el que podremos capturar el evento de «revocación de permisos finalizada» (onAccessRevoked). En nuestro tan solo mostraremos un toast para informar de ello. Veamos cómo quedarían ambas acciones en el evento onMenuItemSelected de la action bar.

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item)
{
	switch (item.getItemId())
	{
		//Cerrar Sesión
		case R.id.action_sign_out:
			if (plusClient.isConnected())
			{
				plusClient.clearDefaultAccount();
				plusClient.disconnect();
				plusClient.connect();

				Toast.makeText(MainActivity.this,
					"Sesión Cerrada.",
					Toast.LENGTH_LONG).show();
			}

			return true;
		//Revocar permisos a la aplicación
		case R.id.action_revoke_access:
			if (plusClient.isConnected())
			{
				plusClient.clearDefaultAccount();

				plusClient.revokeAccessAndDisconnect(
					new OnAccessRevokedListener() {
						@Override
						public void onAccessRevoked(ConnectionResult status)
						{
							Toast.makeText(MainActivity.this,
								"Acceso App Revocado",
								Toast.LENGTH_LONG).show();
						}
					});
			}

			return true;
		default:
			return super.onMenuItemSelected(featureId, item);
	}
}

Y hasta aquí el primer artículo sobre integración con Google+. En el siguiente veremos varias de las funcionalidades que tendremos disponibles al estar conectados con este servicio.

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la pagina del curso en GitHub.

También te puede interesar

17 comentarios

Fede 01/09/2013 - 5:25

Paso a paso como insertar google plus sign- in en nuestra web, video oficial de Google :) http://youtu.be/9Jna_JHh19U

Responder
Gonzalo 11/09/2013 - 1:01

Espero con ansias el próximo articulo!!!

Ya quiero obtener los datos del user y guardarlos en las prefs o algo…sigue asi!!

La integración fue super fácil, nada que ver con Facebook o Twitter, Lastima que no lo usa mucha gente pero bueno, no depende mucho de ellos.

PD: me compre el libro. Excelente el nivel.

Saludos desde Argentina!

Responder
Integración con Google+ (II): Datos de perfil y Círculos | sgoliver.net blog 19/09/2013 - 19:00

[…] el artículo anterior de la serie vimos cómo podíamos incluir en nuestra aplicación la opción de que el usuario se […]

Responder
Juan carlos 27/10/2013 - 2:14

me sale error amigo sale que no se pueden utilizar juntos el peronal y el people

Responder
Ricardo 28/10/2013 - 16:31

Genial tutorial!
Pero si quiero tener más datos asociados a este usuario en un servidor remoto, cómo podría identificarle? es decir hay alguna manera de coger su email o algún token que le distinga unívocamente.

Responder
admin 28/10/2013 - 16:35

Hola Ricardo, en el blog tienes una segunda parte de este artículo que te resolverá tu duda: http://www.sgoliver.net/blog/?p=4178

Responder
Ricardo 02/11/2013 - 17:38

No sé si sólo me pasa a mi, pero el método setVisibleActivities me aparece undefined, a cambio estoy usando el método setActions y parece que ya funciona.

Responder
Adrian 04/11/2013 - 15:53

Hola! una pregunta, sabes como desloguearte de google pero desde otra actividad? gracias! sds!

Responder
Sher 22/07/2014 - 17:56

Hola!!! exelente tuto!!! puedes ayudarme ???
Existe alguna forma de autentificarse con google, pero que este te pida usuario y contraseña, es decir que obligue al usuario a loguearse, en caso de que desee acceder con diferentes cuentas.

Responder
RoydCapella 18/08/2014 - 8:56

Efectivamente, tambien me ha dado indefinido el metodo setVisibleActivities de la linea 41. He decidido cambiarlo por «setActions».

Una pregunta amigo, existira alguna forma de capturar el imei del dispositivo para que este me sirva de token y a traves de esto poder identificar uniquivocamente los dispositivos a los que usuario inicia sesion?

Gracias por compartir tus conocimientos. siempre tus posts estan entre mis preferidos.
Saludos desde Venezuela

Responder
Celisal 26/12/2014 - 4:06

Gracias por la info, excelente una pregunta, tengo dos actividades, la actividad 1 para logearme, y una vez que se haya realizado correctamente el login se abre la actividad 2, pero mi duda es como cerrar la sesion desde la actividad 2, tendras algun ejemplo porfavor.

Responder
Sebas 07/03/2015 - 11:30

Hola, he probado la integración con Google+ y no funciona en las versiones nuevas de android. A ver si puedes actualizarlo a la nueva versión.

Un saludo.

Responder
Guixe94 13/03/2015 - 0:10

Hola!
Podrias actualizar el tutorial para integrarlo en Android Studio???

No consigo hacerlo funcionar..

Gracias!

Responder
manuel 16/04/2015 - 19:16

sería genial que lo actualizaras a android studio.

pero sobre todo, lo que sería genial, es que actualizaras el ejemplo a las nuevas clases que se usan, porque PlusClient esta deprecated y no funciona.

un saludo y gracias por tus tutoriales!

Responder
Ignacio 15/05/2015 - 21:50

Hola!

Por favor actualiza el tutorial para integrarlo en Android Studio.
y si pudieras tambien cuelga el código fuente.

Gracias!

Responder
Miguelangel 25/06/2015 - 6:13

Saludos Salvador Goméz Oliver! Tu Curso es excelente, me ha ayudado mucho en mi aprendizaje y en mi trabajo! Valoro mucho tu esfuerzo de compartirnos tus conocimientos con los demás! Con Respecto al inicio de sesion con Google +, he tenido muchos problemas ya que Google ha ido actualizando muy seguido sus Apis de Google+ y utilizan diferentes componentes al que mencionas en este sección! Y he buscado mucho por internet pero no hay informacion concreta sobre estas nuevas APis de Google+! Seria genial, si ya te has enterado de esto y posees ya dichos conocimientos de las nuevas APis de Google+ que actualizaras esta seccion de inicio de sesion con Google+! Me ayudarias mucho a mi y muchas otras personas! De Antemano, Muchas Gracais por tu curso es un gran aporte para la comunidad Informática! Gracias! :)

Responder
luis adrian vertiz gomez 20/11/2015 - 0:01

hola porque no me puede definir las importaciones de la clase plusClient ??
Saludos

Responder

Dejar un comentario

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. Aceptar Más Información

Política de Privacidad y Cookies