studio purchase play library integradas integrada google facturacion compras app android in-app-billing android-billing

play - Android In App Billing: no se puede iniciar launchPurchaseFlow porque launchPurchaseFlow está en progreso



in-app purchase android studio (6)

Estoy implementando In App Billing por primera vez y estoy probando mis primeras compras usando los id. De SKU estáticos.

Funcionó muy bien la primera vez. Llamé a mHelper.launchPurchaseFlow(...) y mHelper.launchPurchaseFlow(...) la compra de prueba. Mi actividad recibió la onActivityResult llamada onActivityResult y me aseguré de procesarla con mHelper.handleActivityResult(...) . Todo estuvo genial.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // Pass on the activity result to the helper for handling log("onActivityResult"); if (!this.mHelper.handleActivityResult(requestCode, resultCode, data)) { log("cleared the launch flow"); // not handled, so handle it ourselves (here''s where you''d // perform any handling of activity results not related to in-app // billing... super.onActivityResult(requestCode, resultCode, data); } }

Sin embargo, quería probar la siguiente parte, así que relancé la aplicación e intenté comprar el mismo SKU (SKU estático purchased ).

mHelper.launchPurchaseFlow(rootActivity, "android.test.purchased", 10002, new IabHelper.OnIabPurchaseFinishedListener() { @Override public void onIabPurchaseFinished(IabResult result, Purchase purchaseInfo) { if (result.isFailure()) { log("purchased failed"); } else { log("purchase succeeded"); } } }, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");

La segunda vez que trato de comprar el artículo, se llama mi OnIabPurchaseFinishedListener y veo que purchase failed en mi registro: "Error de facturación en la aplicación: no se puede comprar el artículo, respuesta de error: 7: artículo ya propiedad"

Eso tiene sentido, pero si intento comprar otro artículo, mi aplicación se bloquea con el siguiente error:

java.lang.IllegalStateException: no se puede iniciar la operación asincrónica (launchPurchaseFlow) porque otra operación asincrónica (launchPurchaseFlow) está en progreso.

La onActivityResult llamada onActivityResult no ocurre cuando intento hacer la compra que falla, por lo que el flujo de inicio que falló no se maneja y se limpia. Entonces, cuando pruebo otra compra, esa es la razón por la que se cuelga porque aún se supone que está en el medio de la última transacción fallida.

¿Qué estoy haciendo mal? ¿Cómo me aseguro de que launchPurchaseFlow () se limpia después de una falla?


Creo que solo tiene que obtener el código actualizado de las clases de facturación en la aplicación y no debe volver a encontrarse con el mismo problema.

Google no ha enviado los cambios al Administrador de SDK hasta donde yo sé. Solo copie / pegue las nuevas clases en las suyas y no debería seguir teniendo problemas.

Eche un vistazo a los nuevos cambios de código aquí: https://code.google.com/p/marketbilling/source/detail?r=7ec85a9b619fc5f85023bc8125e7e6b1ab4dd69f&path=/v3/src/com/example/android/trivialdrivesample/MainActivity.java

Las clases que se cambiaron a partir del 15 de marzo son: IABHelper.java, Inventory.java, SkuDetails.java y parte del archivo MainActivity.java


No hay necesidad de soluciones hacky. La actividad o fragmento que solicita el flujo de compra debe tener esto:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data); if (billingHelper == null) return; // Pass on the activity result to the helper for handling if (!billingHelper.handleActivityResult(requestCode, resultCode, data)) { // not handled, so handle it ourselves (here''s where you''d // perform any handling of activity results not related to in-app // billing... super.onActivityResult(requestCode, resultCode, data); } else { Log.d(TAG, "onActivityResult handled by IABUtil."); } }

Eso es del proyecto de muestra de Google, lo probé en mi proyecto y funciona.


Para mí, la mejor solución fue tanto para abrir el código al reciente ( here ), y hacer lo que sugiere esta publicación :

1) hacer que el método flagEndAsync público. Está allí, simplemente no visible.

2) haga que cada oyente llame a iabHelper.flagEndAsync para asegurarse de que el procedimiento esté marcado como terminado correctamente; parece ser necesario en todos los oyentes.

3) llamadas de sonido envolvente con un try/catch para atrapar la IllegalStateException que puede ocurrir, y manejarlo de esa manera.

La razón por la que actualizar el código no fue suficiente es porque he encontrado casos especiales donde aún se produce esta falla (o al menos uno):

  • desconectarse de internet;
  • ingrese su aplicación;
  • deja que inicialice el IabHelper ;
  • Conectar a internet;
  • una vez que el dispositivo esté conectado, intente hacer una compra.

Sé que es una especie de contribución tardía a la pregunta, pero estaba enfrentando el mismo problema hoy y estaba llamando a la facturación de la aplicación dentro de un fragmento, así que busqué en "labHelper.java" y vi una solución directa que creo el problema que es ... modifiqué el método "void flagStartAsync (String operation)" en labHelper.java para que sea como el siguiente

void flagStartAsync(String operation) { if (mAsyncInProgress) { flagEndAsync(); } if (mAsyncInProgress) throw new IllegalStateException("Can''t start async operation (" + operation + ") because another async operation(" + mAsyncOperation + ") is in progress."); mAsyncOperation = operation; mAsyncInProgress = true; logDebug("Starting async operation: " + operation); }

Espero que esto ayude a alguien por ahí ...


Tengo el mismo problema.

Primer intento: solución

Descargué el actual IabHelper.java , según la solución de jmrmb80 , pero eso no funcionó. (Parece que el repositorio ahora está en deprecated y debemos confiar en la versión proporcionada por el administrador del SDK de Android). Así que seguí el consejo de Khan :

  • defina IabHelper.flagEndAsync () como público, y
  • agregue iabHelper.flagEndAsync() antes de iabHelper.launchPurchaseFlow(...)

¡Esto parece un hack descarado! Y puede tener efectos secundarios indeseables. Pero, "funciona" ...

Esto parece ser un error conocido: #134 y #189 .

Segundo intento: arreglar

Después de más investigaciones, no creo que la solución anterior resuelva mi problema. Creo que la verdadera solución es anular onActivityResult en el hilo de UI.


Error response: 7:Item Already Owned significa que usted compró el artículo pero aún no lo ha consumido e intenta comprarlo nuevamente.

Esto me sucedió cuando configuré AndroidManifest launchMode en mi actividad en la aplicación para singleInstance . La aplicación siempre terminó con el error que describiste.

Para evitar este comportamiento, cambie su launchMode a cualquier otro valor que se ajuste a sus necesidades android:launchMode="singleInstance" -> android:launchMode="singleTask"

No intenté comprender en profundidad por qué singleInstance no funciona. Si alguien sabe, por favor brinde más información.

Así que mi solución fue cambiar el modo de lanzamiento y consumir el elemento que ya poseía. Desde ese momento IAP funciona bien para mí.