36 votes

Android In App Billing: impossible de lancer launchPurchaseFlow car launchPurchaseFlow est en cours

Je suis en œuvre En Application de Facturation pour la première fois et je suis en essais mes premiers achats à l'aide de la statique SKU id.

Ça a très bien fonctionné la première fois. J'ai appelé mHelper.launchPurchaseFlow(...) et complété le test de l'achat. Mon activité a reçu l' onActivityResult de rappel et j'ai fait en sorte de le traiter avec un mHelper.handleActivityResult(...). Tout a été parfait.

@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);
    }
}

Cependant, j'ai voulu tester la prochaine partie, j'ai donc relancé l'application et a essayé d'acheter la même SKU (statique 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 deuxième fois que j'essaie d'acheter l'article, mon OnIabPurchaseFinishedListener est appelé et je vois purchase failed dans mon journal: "Dans l'application de facturation d'erreur: Impossible d'acheter l'article, Erreur de réponse: 7:l'Élément est Déjà Possédée"

Ce qui est logique, mais si j'essaie d'en acheter un autre élément, puis mon application se bloque avec le message d'erreur suivant:

java.lang.IllegalStateException: ne Peut pas démarrer opération asynchrone (launchPurchaseFlow) car un autre async opération(launchPurchaseFlow) est en cours.

L' onActivityResult de rappel ne se produit pas lorsque j'essaie de faire l'achat d'échec, de sorte que le lancement de flux de qui a échoué, n'obtient pas traitées et nettoyées. Donc, quand j'ai essayer un autre achat, c'est pourquoi il se bloque parce que c'est toujours soi-disant dans le milieu de la dernière transaction a échoué.

Ce que je fais mal? Comment puis-je m'assurer que les launchPurchaseFlow() est nettoyée après un échec?

43voto

jmrmb80 Points 804

Je crois que vous avez juste à obtenir le code mis à jour le dans l'application de facturation des classes et vous ne devriez pas courir sur le même problème à nouveau.

Google n'a pas poussé les modifications apportées à la SDK Manager pourtant, autant que je sache. Il suffit de copier/coller le nouvelles classes dans le vôtre et vous ne devriez pas courir sur le problème plus longtemps.

Regardez le nouveau code des changements ici: https://code.google.com/p/marketbilling/source/detail?r=7ec85a9b619fc5f85023bc8125e7e6b1ab4dd69f&path=/v3/src/com/example/android/trivialdrivesample/MainActivity.java

Les classes qui ont été modifiées à compter du 15 Mars sont: IABHelper.java, Inventory.java, SkuDetails.java et certains de la MainActivity.java fichier

29voto

alazmi95 Points 25

Je sais que c'est une sorte de contribution tardive à la question, mais j'étais confronté au même problème aujourd'hui et j'appelais la facturation dans l'application dans un fragment, alors j'ai regardé dans "labHelper.java" et j'ai vu une solution directe, je crois, pour le problème qui est ... J'ai modifié la méthode "void flagStartAsync (String operation)" dans labHelper.java pour ressembler à ce qui suit

 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);
}
 

J'espère que cela aiderait quelqu'un là-bas ...

10voto

android developer Points 20939

Pour moi, la meilleure solution était de deux udpate le code de la récente (ici), et de faire ce que ce poste vous suggérons:

1) faire une méthode flagEndAsync du public. Il est là, tout simplement pas visible.

2) demandez à chaque auditeur d'appel iabHelper.flagEndAsync afin de s'assurer que la procédure est marqué terminé correctement, il semble être nécessaire dans tous les auditeurs.

3) surround appels avec un try/catch pour attraper l' IllegalStateException qui peut se produire, et de les traiter de cette façon.

La raison que la mise à jour du code n'était pas assez, c'est que j'ai trouvé des cas particuliers où ce bug se produit toujours (ou au moins un):

  • déconnectez-vous d'Internet;
  • entrez votre application;
  • laissez initialiser l' IabHelper;
  • se connecter à l'Internet;
  • une fois que l'appareil est connecté, essayez de faire un achat.

8voto

user2768 Points 36

J'ai le même problème.

Première tentative: solution de Contournement

J'ai téléchargé le courant IabHelper.javacomme par jmrmb80 de la solution, mais cela ne fonctionne pas. (Il semble que l'opération est maintenant obsolète et nous devons nous fier à la version fournie par Android SDK manager.) J'ai donc suivi Khan conseils:

  • définir IabHelper.flagEndAsync() en tant que public, et
  • ajouter iabHelper.flagEndAsync() avant iabHelper.launchPurchaseFlow(...)

Cela semble être un hack flagrante! Et il peut avoir des effets secondaires indésirables. Mais, il ne "travail"...

Cela semble être un bug connu: #134 et #189.

Deuxième tentative: Correction

Après enquête, je ne pense pas que la solution de contournement ci-dessus a résolu mon problème. Je pense que la vraie solution est de remplacer onActivityResult dans le thread de l'INTERFACE utilisateur.

0voto

Honza Musil Points 11

Error response: 7:Item Already Owned signifie que vous avez acheté, mais vous n'avez pas consommé il encore et que vous essayez de l'acheter à nouveau.

Ce qui m'est arrivé lorsque j'ai mis en AndroidManifest launchMode dans mon dans-app acitivité d' singleInstance. Application toujours terminé avec l'erreur que vous avez décrit.

Pour éviter ce comportement, changer votre launchMode à toute autre valeur qui correspond à vos besoins android:launchMode="singleInstance" -> android:launchMode="singleTask"

Je n'ai pas essayer de comprendre profondément pourquoi instance unique ne fonctionne pas. Si quelqu'un sait s'il vous plaît fournir plus d'informations.

Donc ma solution a été de changer launchMode et consomment déjà la propriété de l'élément. Depuis ce temps, PEI fonctionne très bien pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X