Como añadir una licencia a nuestra aplicación

En este apartado vamos a describir los pasos a seguir para usar licencias de Google Play en una de tus aplicaciones. Luego haremos un ejercicio paso a paso para ver estos pasos en la práctica.

A continuación detallamos estos pasos. No es necesario seguir este orden:

1.   Dar de alta la aplicación en Google Play. Para esto es imprescindible disponer de una cuenta en Google Play Developer Console[1]. Dar de alta una cuenta cuesta 25$ para todas las aplicaciones que queramos publicar y por tiempo indefinido.

2.   Obtener la clave de licencia de esta aplicación. Como se ha explicado para cada aplicación registrada en Google Play se van a generar un par de claves RSA. Nosotros solo tendremos acceso a la clave pública.

3.   Añadir la librería LVL a nuestro proyecto. La forma recomendada es copiar las clases directamente al proyecto. Así facilitamos su ofuscación.

4.   Pedir el permiso de licencia. Para ello editaremos el manifiesto de nuestra aplicación y usaremos el permiso correspondiente.

5.   Definir una política de licencias. Hay que definir cosas como lo estricto que vamos a hacer cuando el usuario no disponga de conexión a Internet. Le denegamos la licencia, permitimos una caché, cuánto tiempo… Para implementar esta política podemos crear un descendiente de la clase Policy. Aunque la librería ya incorpora un par de políticas que pueden ser adecuadas para la mayoría de los casos.

6.   Crear una instancia de la clase LicenseChecker. Será nuestro manejador de licencia. Al crearlo hay que indicarle nuestro contexto, la política de licencias y la clave pública de la licencia. El objeto creado establecerá una conexión con un servicio (bind) de la aplicación Google Play cliente de nuestro dispositivo.

7.   Verificar si disponemos de licencia. No tenemos más que llamar al método checkAccess() del objeto creado en el punto anterior. Se trata de un método asíncrono, por lo que para analizar su respuesta tendremos que realizar el siguiente paso.

8.   Implementar la interfaz LicenseCheckerCallback. Esta interfaz define tres métodos callbacks: allow(), dontAllow()y applicationError(). Cada uno de estos métodos será invocado según el resultado de la consulta realizada en el punto anterior.

9.   Llamar al método onDestroy() del  LicenseChecker.  Será necesario cerrar la comunicación entre procesos (IPC) establecida al crear la instancia de esta clase (ver punto 6) para evitar dejar consultas a medias. El sitio ideal para realizar esta llamada es el método onDestroy()de nuestra actividad.

Veamos cómo realizar estos pasos en el siguiente ejercicio:

 

Ejercicio paso a paso: Uso de la librería LVL.

1.    Crea un nuevo proyecto con los siguientes datos. Reemplaza garcia.moreno.pedro por tus apellidos seguido de tu nombre:

Application Name: ObtencionLicencia

Package name: org.garcia.moreno.pedro.obtencionlicencia

Minimum Required SDK: API 4 (1.6)

Target SDK: API 17 (4.2)

Compile With: API 17 (4.2)

Utiliza los valores por defecto para el resto de los campos.

Nota: En este ejercicio no se puede utilizar el paquete com.exampledado que hemos de publicar la aplicación en Google Play y este prefijo de paquete no está permitido. Además vamos a utilizar nuestro nombre para asegurarnos que el nombre del paquete no coincide con el de otros compañeros.

2.     El primer paso será descargar la librería LVL. Para ello, entra en Android SDK Manager  y descarga el paquete Google Play Licensing Library.

3.     Abre la carpeta <sdk>\extras\google\play_licensing\library\src. <sdk> corresponde al directorio donde tienes instalado Android SDK. Para obtener este valor puedes consultar Windows/Preferences/Android/SDK Location. Copia los ficheros que encuentres a la carpeta src de tu proyecto. Puedes arrastrarlos directamente desde el explorador de archivos al Package Explorer de Eclipse.

La forma más habitual de trabajar con una librería es crearla en un proyecto independiente al nuestro. De esta forma, estará disponible en todos los proyectos que creemos y si tenemos que hacer algún cambio afectará a todos los proyectos. Como se explicará más adelante, para facilitar la ofuscación resulta más adecuado copiar el código de esta librería directamente a nuestro proyecto.

4.     Para hacer las pruebas, vamos a introducir dos botones en el layout. Uno que comprobará si la licencia es válida y otro para entrar en la aplicación. Sustituye el contenido de activity_main.xml por el siguiente código:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context=".MainActivity" >

    <Button

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:onClick="comprobarLicencia"

        android:text="Comprobar Licencia" />

    <Button

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:onClick="entrar"

        android:text="Entrar" />

</LinearLayout>

 

5.     A continuación, reemplaza el código de MainActivity por el siguiente. No te olvides de incluir los importsnecesarios:


publicclass MainActivity extends Activity implements LicenseCheckerCallback {

    privatestatic final String CLAVE_PUBLICA_LICENCIA = "Tu clave pública";

    // Genera 20 bytes aleatorios, y reemplazalos por los siguientes.

    privatestatic final byte[] SALT = new byte[] {-46, 65, 30,-128,-103,
                 -57, 74,-64, 51, 88,-95,-45, 77,-117,-36,-113,-11, 32,-64, 89};

    LicenseChecker comprobarLicencia;

    boolean permitir = false;

    ProgressDialog dialogo;

 

    @Override protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        String idDispositivo = Secure.getString(getContentResolver(),                                                                    Secure.ANDROID_ID);

        ServerManagedPolicy politica = new ServerManagedPolicy(this,
                new
AESObfuscator(SALT, getPackageName(), idDispositivo));

        comprobarLicencia = new LicenseChecker(this, politica,                                                              CLAVE_PUBLICA_LICENCIA);

        dialogo = new ProgressDialog(this);

        dialogo.setTitle("comprobando licencia");

        dialogo.setIndeterminate(true);

    }

    public void comprobarLicencia(View view) {

        dialogo.show();

        comprobarLicencia.checkAccess(this);

    }

    public void entrar(View view) {

        if (permitir) {

            Toast.makeText(this,"Entrando en aplicación",
                                                                                        Toast.LENGTH_LONG).show();

        } else {

            Toast.makeText(this, "Licencia no válida",
                                                                                        Toast.LENGTH_LONG).show();

        }

    }

    @Override public void allow(int reason) {

        permitir = true;

        Toast.makeText(this,"Licencia correcta: "+reason,
                                                                                        Toast.LENGTH_LONG).show();

        dialogo.dismiss();

    }

 

    @Override public void dontAllow(int reason) {

        permitir = false;

        Toast.makeText(this,"Licencia no válida: "+reason,
                                                                                        Toast.LENGTH_LONG).show();

        dialogo.dismiss();

    }

    @Override public void applicationError(int errorCode) {

        Toast.makeText(this, "Error al comprobar licencia: " + errorCode,

                                                                                 Toast.LENGTH_LONG).show();

        dialogo.dismiss();

    }

    @Override protected void onDestroy() {

        super.onDestroy();

        comprobarLicencia.onDestroy();

    }

}

En esta actividad comenzados declarando la constante CLAVE_PUBLICA_LICENCIA. Una vez registrada la aplicación en Google Play se creará una clave que tendremos que introducir en esta constante.

Dentro del onCreate(), después de establecer la vista a mostrar, averiguamos el ANDROID_ID del dispositivo. Se trata de un número de 64 bits (expresado en una cadena hexadecimal) que se genera aleatoriamente en el primer arranque del dispositivo y debe permanecer constante durante toda la vida del dispositivo. Luego definimos la política de licencias. Se ha seleccionado una de las predefinidas en la librería (ServerManagedPolicy). Al definir la política también definimos un ofuscador. Típicamente la política de licencias tiene que guardar los datos de respuesta de licencia en un almacenamiento persistente. Por ejemplo, una política podría mantener la fecha de la última comprobación correcta, el número de reintentos, el período de validez de la licencia, etc. Para evitar la manipulación de estos datos resulta conveniente almacenarlos de forma encriptada. En la librería LVL se incluye el encriptador AESOfuscator[1]. Para parametrizarlo hay que indicar tres semillas: una aleatoria (SALT), una que dependa de la aplicación (el nombre del paquete) y una que dependa del dispositivo (idDispositivo).

A continuación creamos un LicenseChecker, que será el encargado de comprobar la licencia. Como argumentos para la creación, le pasamos un contexto, una política y nuestra clave de licencia. Este método termina creando un cuadro de diálogo que será mostrado cuando estemos comprobando la licencia.

Los siguientes dos métodos están asociados a la pulsación de los dos botones. Si pulsamos sobre el botón de comprobar licencia, el código llama a checkAccess(this). El argumento que le pasamos ha de ser un objeto que implemente la interfaz LicenseCheckerCallback; en este ejemplo, nosotros mismos. Si pulsamos en botón «Entrar», simplemente se muestra el valor de la variable permitir.

Los siguientes tres métodos corresponden a la interfaz LicenseCheckerCallback. Uno de estos métodos será llamado tras invocar a checkAccess(). Finalmente, en el método onDestroy()tenemos que asegurarnos que se cierra la comunicación con la aplicación Google Play.

6.     En el manifiesto añade el siguiente permiso:

<uses-permission
                                  android:name="com.android.vending.CHECK_LICENSE" />

No hace falta pedir permiso de Internet, ya que es la aplicación Google Play la que se conectará a Internet para verificar la licencia, y no la nuestra.

7.     En el siguiente paso vamos a dar de alta nuestra aplicación en Google Play Developer Console. Entra en el URL https://play.google.com/apps/publish.

8.     Si no dispones de una cuenta puedes crear una nueva pagando 25$. Durante el curso puedes pedir una autorización para utilizar la cuenta «Android Curso» del usuario androidcurso2013. Tienes que indicar una cuenta de Google al profesor para que la autorice.

9.     Pulsa el botón «+ Añadir nueva aplicación». Introduce en el campo Nombre tu apellido seguido de una coma y de tu nombre. Pulsa el botón «Preparar entrada de Play Store». NUNCA PUBLIQUES LA APLICACIÓN. Para probar la licencia solo es necesario darla de alta en la consola. Tampoco es necesario que introduzcas otros datos de distribución.

10.     El siguiente paso será conseguir la clave pública de la licencia de nuestra aplicación. Podrás ver la clave de licencia dentro de la información de tu aplicación, en la pestaña de Servicios y API. Busca el campo «Tu clave de licencia para esta aplicación», cópialo y pégalo como valor para la constante CLAVE_PUBLICA_LICENCIA, definida al principio de MainActivity.

LICENCIAS Y FACTURACIÓN INTEGRADAS EN APLICACIONES

Nota: La licencia permite evitar la distribución no autorizada de la aplicación. También puedes utilizarla para verificar las compras de facturación integrada en la aplicación. Más información sobre licencias.

TU CLAVE DE LICENCIA PARA ESTA APLICACIÓN

Clave pública RSA codificada en base 64 para incluirla en tu código binario. Elimina todos los espacios.

11.     Firma la aplicación con un certificado definitivo y crea el APK. Para ello puedes utilizar la opción File/Export…/Export Android Application. Para más información, puedes ver el Vídeo[Tutorial]:Firmar una aplicación Android.

12.     Ahora, tendrás que subir el APK ya firmado a Google Play. Selecciona la pestaña APK y luego la pestaña BETA TESTING. Luego, Subir nuevo APK.

13.     Aunque la aplicación aún no ha sido publicada, vamos a poder testearla gracias a la licencia para pruebas. Entra dentro de Google Play Developer Console y, en la izquierda, selecciona la pestaña de Configuración (). Si no eres el propietario de esta consola, añade tu cuenta de Gmail en la lista de licencias para pruebas:

 

14.     Justo debajo puedes configurar la respuesta que dará el servidor para todas las aplicaciones con licencia de prueba. Si otros compañeros están haciendo pruebas es posible que se modifique este valor.

15.     Ejecuta la aplicación sobre un terminal real. Puedes instalar el APK firmado o el que genera Eclipse en modo debug. Es indiferente dado que para verificar la licencia solo se utiliza el nombre del paquete, no se tiene en cuenta si está firmada.

Nota: La verificación de licencia se hace con la cuenta primaria del dispositivo.

Nota: Si la aplicación está en modo borrador y haces una consulta con una cuenta que no está en el listado, se asume que has conseguido el APK directamente de los desarrolladores y que eres un beta tester. En este caso siempre devuelve LICENSED.

16.     Después de pulsar sobre el botón de comprobar licencia, se mostrará en un toast la respuesta del servidor. Si aparece el «Error al comprobar licencia: 3» quiere decir que Google Play desconoce el paquete (ver tabla de errores al final). Tendrás que esperar alrededor de media hora hasta que se actualice la información en los servidores de Google Play.

17.     Pasado este tiempo, pon el valor de Respuesta de licencia de prueba a LICENSED y verifica que obtienes la licencia. El botón «Entrar» te permitiría entrar en la aplicación.

18.     Pon el valor de Respuesta de licencia de prueba a NOT_LICENSED y verifica que ya no obtienes la licencia desde tu aplicación.

19.     Introduce otros valores en Respuesta de licencia de prueba y verifica el resultado en tu aplicación. La lista de posibles respuestas y errores se muestra a continuación:

valor

Identificador

Descripción

256

LICENSED

La licencia es válida.

561

NOT_LICENSED

La licencia no es válida.

291

RETRY

No se ha podido conectar con el servidor.
Se debería reintentar.

Valores posibles del parámetro en los métodosallow(int) y dontAllow(int) de la interfaz LicenseCheckerCallback.

 

valor

Identificador

Descripción

1

 

INVALID_PACKAGE_NAME

 

Paquete no instalado

2

NON_MATCHING_UID

Se pide un paquete distinto al de la app
actual.

3

NOT_MARKET_MANAGED

Google Play desconoce el paquete.

4 CHECK_IN_PROGRESS Una comprobación se está realizando.
Solo se permite una comprobación a la vez.
5 INVALID_PUBLIC_KEY La clave púbica es incorrecta.
6 MISSING_PERMISSION Falta el permiso com.android.vending.CHECK_LICENSE.

Valores posibles del parámetro en el métodoapplicationError(int) de la interfaz LicenseCheckerCallback.