Android En la facturación de la aplicación: No se puede iniciar launchPurchaseFlow porque launchPurchaseFlow está en curso

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

Funcionó muy bien la primera vez. Llamé a mHelper.launchPurchaseFlow(...) y mHelper.launchPurchaseFlow(...) la compra de la 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 relanzé la aplicación e intenté comprar la misma SKU (la estática purchased SKU).

 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 intento comprar el artículo, se llama a mi OnIabPurchaseFinishedListener y veo que la purchase failed en mi registro: "Error de facturación en la aplicación: No se puede comprar el artículo, Respuesta de error: 7: Elemento que ya se posee"

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

Java.lang.IllegalStateException: No se puede iniciar la operación asíncrona (launchPurchaseFlow) porque otra operación asíncrona (launchPurchaseFlow) está en curso.

La onActivityResult llamada onActivityResult no sucede cuando intento hacer la compra que falla, por lo que el flujo de lanzamiento que falló no se maneja y se limpia. Así que, cuando intento otra compra, es por eso que se bloquea porque todavía está supuestamente en medio de la última transacción fallida.

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

Creo que sólo tiene que obtener el código actualizado de las clases de facturación en la aplicación y no debe ejecutar en el mismo problema de nuevo.

Google aún no ha enviado los cambios al SDK Manager hasta donde yo sé. Basta con copiar / pegar las nuevas clases en la suya y no debe ejecutar en el problema por más tiempo.

Echa 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 fueron cambiadas a partir del 15 de marzo son: IABHelper.java, Inventory.java, SkuDetails.java y parte del archivo MainActivity.java

Sé que es una especie de contribución tardía a la pregunta, pero yo estaba enfrentando el mismo problema hoy y estaba llamando a la facturación dentro de la aplicación dentro de un fragmento, por lo que busqué en "labHelper.java" y vi una solución directa creo El problema que es … He modificado el método "void flagStartAsync (String operation)" en labHelper.java para ser 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í …

Para mí, la mejor solución fue tanto para udpate el código de la reciente ( aquí ), y hacer lo que este post sugieren:

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

2) tener cada oyente llamada iabHelper.flagEndAsync para asegurarse de que el procedimiento está marcado terminado correctamente; Parece ser necesario en todos los oyentes.

3) rodea las llamadas con un try/catch para capturar la IllegalStateException que puede ocurrir y manejar de esa manera.

La razón de que la actualización del código no fue suficiente es que he encontrado casos especiales en los que este error todavía se produce (o al menos uno):

  • Desconectarse de Internet;
  • Ingrese su aplicación;
  • IabHelper inicializar el IabHelper ;
  • Conectar a internet;
  • Una vez que el dispositivo está conectado, intente realizar una compra.

Tengo el mismo problema.

Primer intento: Solución

He descargado el IabHelper.java actual, según la solución de jmrmb80 , pero eso no funcionó. (Parece que el repo ahora está en desuso y debemos confiar en la versión suministrada por el administrador de SDK de Android). Así que seguí el consejo de Khan :

  • Define IabHelper.flagEndAsync () como público y
  • Agregar iabHelper.flagEndAsync() antes iabHelper.launchPurchaseFlow(...)

¡Esto parece un truco flagrante! Y puede tener efectos secundarios indeseables. Pero, "funciona" …

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

Segundo intento: Fijar

Después de más investigación, no creo que la solución anterior resuelto mi problema. Creo que la solución real es anular onActivityResult en el subproceso de interfaz de usuario.

Error response: 7:Item Already Owned significa que has comprado un artículo pero aún no lo has consumido e intentas volver a comprarlo.

Esto me pasó cuando me puse en launchMode de AndroidManifest en mi actividad de aplicación a singleInstance . La aplicación siempre termina con el error que describió.

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

No intenté entender profundamente por qué singleInstance no funciona. Si alguien sabe por favor proporcione más información.

Así que mi solución fue cambiar launchMode y consumir el elemento ya poseído. Desde entonces IAP funciona bien para mí.

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 ejemplo de Google, lo probé en mi proyecto y funciona.

  • Error en la autorización de facturación del operador con facturación en la aplicación de Google
  • Estado de prueba gratuita de suscripción de IAB
  • Facturación en la aplicación de Google Play v3 getSkuDetails () devuelve los resultados almacenados en caché incluso si se modificaron los precios de la IAP
  • ¿El mejor acercamiento para las versiones libres y pagadas de la aplicación de Androide?
  • Error de facturación en la aplicación de Android Error: Este artículo no se pudo comprar. (Código de error: IAB-DPTL)
  • In-App Billing v3, obligación bindService () no se puede encontrar
  • NullPointer en startIntentSenderForResult, no aplicando V3
  • Error: esta versión de la aplicación no está configurada para la facturación a través de Google Play
  • Error en la facturación de Android en la aplicación, diciendo "Ya tienes una orden pendiente para este elemento".
  • Diferencia entre IABHelper y IInAppBillingService en InAPPBilling
  • Google Play Store está dando créditos adicionales al usuario?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.