Integración con Google+ (I): Google+ Sign-In
Este material es tomado de http://www.sgoliver.net
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”.
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).
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:
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”.
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:
1
2
3
4
| < 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 clasePlusClient, 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 yListenActivity 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| @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( .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.
1
2
3
4
5
6
7
8
9
10
11
12
13
| @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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| 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 aconnect() no finaliza correctamente. Este evento recibe como parámetro un objeto de tipoConnectionResult 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
| 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 objetoConnectionResult 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étodostartResolutionForResult(). 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+.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| 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 eventoonConnected() del que ya hemos hablado).
1
2
3
4
5
6
7
8
9
10
| @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 eventoonConnectionFailed() quedaría finalmente de la siguiente forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| @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étododismiss() del diálogo, quedando finalmente así:
1
2
3
4
5
6
7
8
| @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.
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:
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+.
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étodosetVisibleActivities() 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 arevokeAccessAndDisconnect() 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 onMenuItemSelectedde la action bar.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| @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.
Comentarios
Publicar un comentario