Como implementar las compras integradas en vuestra aplicación Android - Billing Products

Hola de nuevo chic@s! antes de que se me olvide (mi memoria es limitada) jejejeje quiero compartir como he integrado las compras integradas en mi aplicación a traves de googlePlay Services.

¿einnnn? ¿que es esto de las compras integradas de google Play Services? pues es un servicio que tiene google para hacer compras de productos dentro de las aplicaciones, por ejemplo: Una licencia PRO, elementos de los juegos (vidas o dinero virtual), etc...

Antes de empezar, todo lo que explico aquí esta en la documentación oficial de google sobre las compras integradas, por lo que podéis completar esta lección con esa información.

Yo, actualmente estoy trabajando en una aplicación que dispone de 2 tipos de "cosas pá comprar". Por un lado (la primera), una licencia permanente, es decir una cosa que compras y no caduca, la disfrutas para siempre (aunque desinstales la aplicación), en mi caso concreto es una "licencia" que convierte la aplicación "normal" en una versión PRO con funcionalidades "extras".

Android Kit Kat 4.4

La otra "cosa" pá comprar (la segunda) es un consumible, es decir, la compras y la gastas por lo que vuelve a estar disponible para volver a comprar. En mi caso concreto es un Servicio. Estos son los dos conceptos que tiene google para esto de las compras, y como te digo, voy a poner aquí el codigo que e utilizado en mi aplicación para cada una de los dos tipos. ¡¡Empecemos!!

Todo esto que te he explicado viene dentro de la nueva API v3 para las compras integradas, este tipo de compras o productos, google las llama "Productos Administrados", hay otro tipo que los llama "subscripciones", que un tipo de compra con periocidad (por ejemplo una suscripción mensual, semanal, anual....) para implementar este ultimo tipo es el mismo codigo, lo único que se pasa un parámetro distinto (ya te diré cual), pero bueno, lo importante aquí es saber que necesitas hacer para implementarlo, tienes que hacerlo siguiente: (lo detallo mas adelante)

1. Añadir la biblioteca de facturación en el proyecto (yo todavía uso Eclipse)
2. Añadir el permiso especifico en AndroidManifest.xml.

<uses-permissionandroid:name="com.android.vending.BILLING"/>

3. Crear un ServiceConnection y enlazarlo al IInAppBillingService en el OnCreate de nuestra app. (esto son 10 líneas de codigo, mas abajo te digo como y cuales son ;P)
4. Enviar las solicitudes de compra a googlePlay Services (con un intent) desde su aplicación para IInAppBillingService. (previamente hay que crear un producto integrado en la consola de desarrollador de googlePlay dentro de la aplicación que vayas a publicar)
5. Consumir la compra para que vuelva a estar disponible (para el caso de los servicios solo).

1. Añadir la biblioteca de facturación en app en nuestro proyecto.

Primero: con el Android SDK Manager d descargarte la librería"Google Play Billing".

descargar libreria billing in app

 

Segundo: abre el explorer y localiza la libreria, se descargara en: <sdk> / extras / google / play_billing /

Tercero: Después, en Eclipse, crea una nueva carpeta dentro de <src>. (haz click en: File>New>Package) llamalo com.android.vending.BILLING y copia el fichero IInAppBillingService.aidl que localizaste en el paso segundo a esa carpeta (arrastrala desde la ventana del explorador a la carpeta de eclipse)

crear carpeta dentro del proyecto com.android.vending.billing

 

2. Añadir el permiso especifico en AndroidManifest.xml.

Esto es fácil ¿no? si estas aquí es porque estas cosicas ya las as hecho (eso espero) jejejej

<uses-permissionandroid:name="com.android.vending.BILLING"/>
Android Kit Kat 4.4

 

3. Crear un ServiceConnection y enlazarlo al IInAppBillingService en el OnCreate de nuestra app.

Bueno, esto suena mu tecnico ¿no? la verdad es que esta parte tiene un poco de miga, por un lado hay que tener un par de métodos (ponerlos al final del proyecto) y luego hay que poner codigo dentro del OnCreate de la Activity donde vayamos a realizar la compra y en el OnDestroy para matar ese servicio que creamos de consulta y no consuma memoria cuando cerremos nuestra app.

Os lo pongo por partes, primero en el OnCreate:

//crea esta variable GLOBAL
IInAppBillingService mService;


//Este codigo va justo despues del Oncreate

Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE)

Esto seria para el metodo OnDestroy, que como he dicho antes, es para matar el servicio cuando salgamos de esa activity.

Override
public void onDestroy() {
    super.onDestroy();
    if (mService != null) {
        unbindService(mServiceConn);
    }   
}

Y esta parte ponla donde quieras de tu proyecto, son métodos aparte para realizar la conexion, y que son llamados al ejecutar el codigo que pusiste en el OnCreate.

//Este codigo ponlo al final de tu proyecto, son los metodos del codigo anterior
ServiceConnection mServiceConn = new ServiceConnection() {
   @Override
   public void onServiceDisconnected(ComponentName name) {
       mService = null;
   }

   @Override
   public void onServiceConnected(ComponentName name, 
      IBinder service) {
       mService = IInAppBillingService.Stub.asInterface(service);
   }
};

Con todo lo anterior, creamos un Servicio Asíncrono, que nos permitirá intercambiar información con los servicios de Google, o bien para realizar compras, o bien para consultar el estado de la licencia.

Os adjunto también un fragmento del codigo real de mi app, fíjate que antes del OnCreate defino una variable GLOBAL del tipo IInAppBillingService porque a esto se llama desde distintas partes de tu programa, y así es mejor.

Ejemplo de como queda el codigo  IINAppBillingService

 

4. Enviar las solicitudes de compra a googlePlay Services

Ya esta hecho casi todo!! ya solo queda realizar la petición de compra a través del servicio que creamos en el paso anterior.

Este punto es un poco lioso al principio, analicemos el metodo que uso para comprar.

// lanzo petición de compra1
comprar("android.test.purchased", "inapp", 1001);

Paso 3 parámetros para la compra:
(1) El nombre del SKU. Es el ID de la compra integrada que tuviste que crear antes en tu consola de desarrollador, esto es complicado, porque cuando estas creando la app y todavía no la tienes subida... joe es la pescadilla que se muerde la cola ¿no? yo hice una versión Alpha y lo cree todo, ademas hay una parte (dentro de los setting de la cuenta) donde incluyes cuentas de google para TESTING y no se hacen cargos reales.

Google tiene unas SKU pre-establecidas (es la del ejemplo) para que no tengas que crear toda esta parafernalia antes, están disponibles en la documentación oficial aquí te resumo que son las siguientes (escribe las tal cual, con puntos y todo).

SKU de prueba de google

 

Si quieres crear las tuyas propias lo tienes aquí (estas son las mías de prueba)

imagen que describe la uvicacion de los productos integrados dentro de la consola de desarrollados de google

 

Esta es la parte para incluir lo de las cuentas TESTING y que no se cargue dinero real en la cuenta del tester

para poner las cuentas de testing

 

(2) El tipo de compra. Como es de tipo "producto Administrado" hay que poner el parámetro"inapp", si queremos hacer una suscripción, aquí pondríamos"subs".

(3) Codigo de petición. Si hacemos varios tipos de compras, debemos pasar distintos códigos de petición para luego capturar el resultado dependiendo de la compra que hacíamos

Como digo este es el codigo completo:

// lanzo petición de compra1
comprar("android.test.purchased", "inapp", 1001); // METODO PARA REALIZAR LAS COMPRAS. Se pasa parametro SKU, TIPO y codigo de peticion: public void comprar(String SKU, String TYPE, int reqcode) throws AndroidException { // codigo venta, genero la peticion de la liecencia Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), SKU, TYPE, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ"); // genero el pendig intent PendingIntent pendingIntent = buyIntentBundle .getParcelable("BUY_INTENT"); // compruebo que la respuesta es 0, si no no se puede comprar if (buyIntentBundle.getInt("RESPONSE_CODE") == 0) { startIntentSenderForResult(pendingIntent.getIntentSender(), reqcode, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)); } else { switch (buyIntentBundle.getInt("RESPONSE_CODE")) { case 7: salvar_int("licencia", 1); Toast.makeText(this, "Esta Licencia ya esta comprada!", Toast.LENGTH_LONG).show(); break; default: Toast.makeText(this, "Error desconocido", Toast.LENGTH_LONG) .show(); } } } //Metodo que recibe el resultado del intent de la compra @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { int responseCode = data.getIntExtra("RESPONSE_CODE", 0); String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA"); String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE"); switch (requestCode) { case 1001: if (resultCode == RESULT_OK) { try { JSONObject jo = new JSONObject(purchaseData); String sku = jo.getString("productId"); salvar_int("licencia", 1); Toast.makeText( this, "Tu has comprado " + sku + ". Excelente eleccion, disfruta!", Toast.LENGTH_LONG).show(); } catch (JSONException e) { // alert("Failed to parse purchase data."); Toast.makeText(this, "Fallo al terminar la compra!!", Toast.LENGTH_LONG).show(); e.printStackTrace(); } } break; case 1002: if (resultCode == RESULT_OK) { try { JSONObject jo = new JSONObject(purchaseData); // guardo datos de compra para consumir String sku = jo.getString("productId"); salvar_str("token2", jo.getString("purchaseToken")); // salvo licencia y notifico salvar_int("licencia2", 1); Toast.makeText( this, "as comprado el Servicio: " + sku + ". Ahora puedes mandar tu informe!, gracias!", Toast.LENGTH_LONG).show(); } catch (JSONException e) { // alert("Failed to parse purchase data."); Toast.makeText(this, "Fallo al terminar la compra!!", Toast.LENGTH_LONG).show(); e.printStackTrace(); } } break; } }

Si todo fue bien, debes obtener algo asi. Ten encuenta que debes de firmar tu app con tu firma, es decir, si usas Eclipse para firmar la app, no te funcionara y dará un error de firma de app, tienes que compilar el APK e instalarlo en el movil.

ejemplo compra billing in app

 

5. Consumir la compra (si es un consumible)

Ya solo queda consumir la compra en los casos de que esta no sea permanente y sea un consumible (como un servicio). Hay que hacer una petición a googlePlay Servicies, pasando como parámetro adicional el Token de la compra que hicimos previamente y que capturamos en el ActivityForResoult (mira codigo de mas arriba).

Este seria el método que se usaría:

 // comprar servicio
comprar("servicio_envio_informe2", "inapp", 1002);
				
	// BOTON ENVIAR INFORME Y CONSUMIR COMPRA
	public void b_enviar_informe(View v) throws AndroidException {

		int response = mService.consumePurchase(3, getPackageName(), "token de la compra anterior");

		switch (response) {
				
		case 0:
			Toast.makeText(this, "codigo:" + response + ", Informe enviado!",
					Toast.LENGTH_SHORT).show();
			
			break;

		case 5:
			Toast.makeText(this,
					"codigo:" + response + ", error de firma de app!",
					Toast.LENGTH_LONG).show();

			break;

		default:
			Toast.makeText(this, "error!, codigo:" + response,
					Toast.LENGTH_LONG).show();

			break;

		}

	}
				
				

 

Si te a gustado este sitio, por favor haz click en me gusta en Facebook, Google+, Tweeter... es el único precio que te pido por este trabajo! ;P. Compartiendo, ayudaras a otros a encontrar esta web! GRACIASSSS.