Uygulama İçi Faturalandırma testi: android.test.purchased zaten sahip olunan


122

Şu anda Uygulama İçi Faturalandırmayı gelecekteki bir uygulama için test ediyorum ve "android.test.purchased" test öğesini ilk kez başarıyla "satın aldıktan" sonra, şimdi tekrar satın almaya çalıştığımda 7 yanıt kodunu alıyorum. bu, bu öğeye zaten sahip olduğum anlamına geliyor.

12-15 23: 02: 14.149: E / IabHelper (19829): Uygulama içi faturalama hatası: Öğe satın alınamıyor, Hata yanıtı: 7: Öğe Zaten Sahiptir

Anladığım kadarıyla, bu satın alma işleminin her zaman mümkün olması gerekiyor, değil mi? Geliştiricinin uygulamasını test edebilmesi için mi?

Değilse, durumunu sahipsiz olarak nasıl "sıfırlayabilirim"? Google Uygulama İçi Faturalandırma Örneğindeki kullanım paketini kullanıyorum.


1
Benim işe alım mesajı zaten sahip ama onun almasına olanak sağlayacak her zaman ihtiyaç mengene ayetler ..Ben ise
Sandeep P

Yanıtlar:


109

Tüketim talebini başlatmak için bu kodu bir iş parçacığına ekleyin.

int response = mService.consumePurchase(3, getPackageName(), purchaseToken);

Satın alma testi için burada buyToken

purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";

Ve

if (response == 0)

o zaman tüketim başarılı olur.

ayrıca mService'i herkese açık hale getirmeyi unutmayın

IabHelper.Java

o zaman şu şekilde erişim mümkün olacaktır:

int response = mHelper.mService.consumePurchase(3, getPackageName(), purchaseToken);

2
Efsane bu işe yarıyor, @psykhi gerçekten size puan vermiş olmalı. Onu tüketmeye çalışıyordum ama satın alma jetonunu çözemedim. Teşekkürler
Blundell

1
Teşekkür ederim! @prasharonnet
Y2i

1
Bu çok büyük bir zaman tasarrufu sağlar. Mükemmel. Teşekkürler.
PrivusGuru

13
MService nedir? mHelper? Ama tüketmekPurchase ()
Bagusflyer

1
mService, uygulama içi satın alma için başlatılan satın alma hizmetiyle bağlantılı olan IInAppBillingService.aidl arayüzünün nesnesidir.
Aashutosh Sharma

92

Herhangi bir özel tüketim kodu yazmaya gerek yok. Google Play Store verilerini temizlemek için adb komutunu kullanmanız yeterlidir:

adb shell pm clear com.android.vending

1
teşekkürler, hile yaptı, sadece uygulamayı da temizlemem gerekiyordu, bu yüzden tam bir cevap verdim. Bu benim için doğru yaklaşım.
sivi

Bu, birçok insan için doğru yaklaşımdır. Uygulamanıza kod eklemek ve yeniden dağıtmak daha fazla zaman alır (amaçlanan).
Michael Labbé

9
Bu, bir test cihazı için iyi bir çözümdür, ancak dikkatli olun: Google Play Store uygulamasındaki tüm ayarlarınızı sıfırlayacaktır. Bu yüzden kişisel cihazımda yapmamayı tercih ederim.
2016

7
Hayır! bu kötü bir fikir, diğer ürününüzün ve diğer uygulamaların uygulama içi satın alımını kaybettiniz, iyi olanı, uygulama içi satın alımınızı test etmek istiyorsanız ürünü tüketmek zorundasınız, senaryo, biri satın almak ve diğeri satın almak için iki şey oluşturmaktır öğe.
Rahul Mandaliya

2
@RahulMandaliya Uygulamanız, halihazırda satın alınmış olanı bilmek için getPurchases () API'sini kullanarak önbellek temizlemelerine karşı dayanıklı olmalıdır.
mttmllns

66

Android.test.purchased öğenin normal bir kimlik gibi davrandığı ortaya çıktı. Bu, tekrar satın alabilmek istiyorsanız, kodunuzda bir yerde tüketmeniz gerektiği anlamına gelir. Google belgelerinin bu konuda yanıltıcı olduğunu ve test amacıyla sonsuza kadar satın alabileceğiniz başka bir statik kimlik eklemeleri gerektiğini düşünüyorum.


Satın alma nesnesini almak için envanter çağrısını kullanın ve sonra onu tüketin - bir kez etrafından dolaştığınızda oldukça kolaydır.
slott

3
Aşağıdaki @mttmlins yanıtına bakın veya vvse.com/blog/blog/2016/08/26/…
IgorGanapolsky

Tamamen doğru değil, tüketilmemiş test öğesinin olduğu bir durumum var, ancak billingClient.queryPurchases()bu tüketilmemiş öğeyi iade etmiyorum, bu yüzden şimdi purchaseTokenonu
alamadığım için tüketemiyorum

28

Uygulama içi sürüm 3:

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {

        .....................

        if (inventory.hasPurchase(SKU_CONTENT)) {

            mHelper.consumeAsync(inventory.getPurchase(SKU_CONTENT), null);
        }
    }
};

Bir resim bin kelimeye bedel olduğundan, tam bir çalışan çıplak kemik kod parçası bin değerindedir 'Bu kodu bir iş parçacığına ekleyin. . . '.
Androidcoder

11

Sürüm 3 - Çözmenin en hızlı yolu : Google Play Store önbelleğini temizlemek, "android.test.purchased" ın tekrar kullanılabilir olmasını sağlayacaktır.


Bu, sistemde yüklü olan diğer uygulamaları da etkilemez mi?
IgorGanapolsky

1
@IgorGanapolsky, hayır. Yalnızca simüle edilmiş satın alımlar etkilenecektir. "Gerçek" satın alımlar Google'ın sunucusunda saklanır ve değiştirilmez.
Denis

1
Google Play uygulama verilerini temizledim ama işe yaramadı. Test satın alma ayrıntıları hala mevcuttur.
Srikar Reddy

2
@Richard "ayarlar / uygulama yöneticisi /" aracılığıyla veya menüden Google Play Store simgesini "bilgi" düğmesine (ekranın üst kısmında) sürükleyerek. Son olarak, "önbelleği temizle" düğmesini tıklamanız yeterlidir.
Denis

1
Benim için en iyi cevap. Diğerlerinin hepsi iyi, ancak bu kesinlikle çözmenin en hızlı yolu
Ignacio Roda


9

Öğeyi bu şekilde tüketebiliriz

 consume.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    String purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";
                    try {
                        Log.d("","Running");
                        int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
                        if(response==0)
                        {
                            Log.d("Consumed","Consumed");
                        }else {
                            Log.d("","No"+response);
                        }
                    }catch (RemoteException e)
                    {
                        Log.d("Errorr",""+e);
                    }

                }
            });
            t.start();
        }
    });

Benim için çalıştı - android.test.purchasesorunlara neden olan bir noktada kullanmıştı - uygulama içi faturalandırmadaki envanter görevi bir sürü hata yaptı ve hiç bitmedi. Bunu bir kereye mahsus olarak çalıştırmak sorunu çözdü, böylece kendimi gerçek SKU'mda kullanmaya devam edebilir ve daha önce olduğu gibi devam edebilirdim. Teşekkürler
Jon

1
Mükemmel cevap. Statik Yanıtlarla Çalışır = Uygulama İçi Faturalandırmanın etkin olduğu apk Google Play'e yüklenmeden önce.
infero

Teşekkürler! Benim için çalıştı.
AndroidMechanic - Viral Patel

6

Kanımca, programınız öğeyi tüketecek şekilde tasarlanmadıysa, dışarıdan bir satıcının belleğini temizlemek için kodu değiştirmenize gerek yoktur. Bu, kodunuzu daha kırılgan hale getirecek ve daha sonra yazılımınıza ait olmayan kodu eklemek ve kaldırmak için çok zaman harcamanız gerekecek, bu nedenle böyle bir çözümü uygulamak kötü bir tasarımdır.

Android.test.purchased'i temizlemek için benim için çalışan en iyi çözüm

adb uninstall com.yourapp.name

ve sonra

adb shell pm clear com.android.vending

Nakit ödemem ve uygulama ayarıma göz atmam veya bunun için kodu değiştirmem gerekmedi. Adb'yi Windows sisteminin yol değişkenlerine eklemem gerekiyordu ki bu oldukça basitti. Yani evet, muhtemelen ihtiyacınız olan adb'yi kullanmanız gerekiyor, bu yüzden ..

Sadece C: \ ... \ android-sdk \ platform-araçlarınızı ekleyin; ortam değişkenlerinde windows yolunda ve mac ve linux işletim sisteminde de oldukça basit olduğunu hayal ediyorum. Umarım, birisinin uygulama faturalarında android uygulamasıyla birkaç gün daha az harcamasına yardımcı olur.


uninstallandroid.test.purchased sku'yu temizlemek gerekli değildir .
IgorGanapolsky

4

Asıl sorun, android.test.purchasedeşyayı tüketmek zorunda olmanızdır . Ancak bu öğe sorgu envanterinizde bulunmayacağı için normal akışı kullanarak tüketemezsiniz.

Dolayısıyla, IabHelpersınıfta IabHelper kullanıyorsanız , geçici olarakIInAppBillingService IabHelper'ınızdan erişilebilir olması için mService'i olarak genel .

Sonra sınıfınızda böyle tüketebilirsiniz,

int response = mHelper.mService.consumePurchase(3, getPackageName(), "inapp:"+getPackageName()+":android.test.purchased");

Başarılı olursa, yanıt 0 olacaktır.

Bu yardımcı olur umarım.


Teğet: Yönetilen bir öğe için para iadesi yapabilir misiniz (bir test hesabıyla - kontrol panelinde görünmüyor)?
Ed Lee

Android.test.purchasedconsumeAsync() üzerinden arayabilirsiniz . Bunda bir sorun yok.
IgorGanapolsky

Basit bir test için bu, IabHelper kullanıyorsanız mümkün olan en iyi yoldur. Bana yardımcı oldu.
Rúben

2

Test amaçlı olarak, gp satın alma akışını başlatan bir yöntemi çağırmadan önce satın aldığınız tüm ürünleri temizleyecek bir kod parçası eklemenizi de öneririm. Şu anda sadece bir öğeyi test ettiğinizde bu özellikle rahattır. Örneğin, bunun gibi:

PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
    for (Purchase sourcePurchase : purchasesResult.getPurchasesList()) {
        if(sourcePurchase != null){

            ConsumeResponseListener listener = new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(String outToken, @BillingResponse int responseCode) {

                    System.out.println("all consumed");
                }
            };
            mBillingClient.consumeAsync(sourcePurchase.getPurchaseToken(), listener);
        }else{
            System.out.println("null");
        }
    }

// and then initiate whole process with clear "shoping basket"

BillingFlowParams.Builder builder = new BillingFlowParams.Builder()
        .setSku(itemName).setType(BillingClient.SkuType.INAPP);

2

Google Play konsoluna gidin ve Sipariş Yönetimi sekmesini açın. Orada test satın alımlarını iade edebilir / iptal edebilirsiniz.


1

Test ortamındaysanız

1) android.test.purchased durumunda, sahte ödemeyi android cihazı yeniden başlatarak sıfırlayabilirim (envanteri tüketebilirim).

2) InApp util'de Security.java adlı bir dosya var ve bunu geçici olarak aşağıdaki gibi yapın. Test ödemesi (sahte) güvenlik istisnası nedeniyle her zaman yanlış döndürdüğünden.

public static boolean verifyPurchase(String base64PublicKey,
                                     String signedData, String signature) {
    return true; }

Sonra OnIabPurchaseFinishedListener içinde fechInvForconsumeItem ()

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
            if (result.isFailure()) {
                // Handle error
                Log.e("123","Failure");

                return;
            }
            else if (purchase.getSku().equals(ITEM_SKU)) {
                Log.e("123","PURCAsed");
                fechInvForconsumeItem(); // Restart device if not consume

            }

        }
    };

FechInvForconsumeItem ()

    public void fechInvForconsumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
        = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result,
                                         Inventory inventory) {


        if (result.isFailure()) {
            // Handle failure
            Log.e("11","Failure");



        } else {
            Log.e("11","suc");
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
                    mConsumeFinishedListener);
        }


    }
};

Dinleyiciyi Tüket (şimdiki değeri)

    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
        new IabHelper.OnConsumeFinishedListener() {
            public void onConsumeFinished(Purchase purchase,
                                          IabResult result) {

                if (result.isSuccess()) {
                } else {
                    // handle error
                    Log.e("11","sucConsume");
                }
            }
        };

0
IabHelper.QueryInventoryFinishedListener 
       mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
       public void onQueryInventoryFinished(IabResult result, Inventory inventory)   
       {
          if (result.isFailure()) {
             return;
           }          
          try {

                if(inventory.hasPurchase("product_sku_id"))
                {   
                     isItemEnable= true;
                     mHelper.consumeAsync(inventory.getPurchase("product_sku_id"),null);            
                }
                else
                {
                       isItemEnable = false;
                }           

            } catch (Exception e) {
                e.printStackTrace();
            }
       }

    };

-1

Benim durumumda, Google'ın öğe için bir satın alma kaydetmediği anlaşılıyor. Bunun yerine, Google Play Hizmetlerinin yerel kopyası satın alma işlemini önbelleğe alır. Böylelikle aynı cihazda ikinci bir talep yapıldığında android.test.purchased already ownedbelirir. Ancak, başka bir cihaz kullanmak veya cihazı sıfırlamak önbelleği temizler ve satın alma işleminin tekrarlanmasına izin verir.


-1

Benim durumumda, sadece uygulama önbelleğini temizlemem gerekiyordu. Önbelleği temizledikten sonra satın alma akışını yeniden başlatabildim.

Cihazımdan (4.4.2) "Ayarlar-> Uygulama yöneticisi" ne gittim. Ardından, "İNDİRİLENLER" sekmesinden uygulamayı ve ardından "Önbelleği temizle" yi seçtim.


-2

Bu, sarf malzemesi ve sarf malzemesi olmayan öğeler arasındaki farktır; Sarf malzemesi olmayan öğelerin (burada uğraşıyor gibi göründüğünüz şeyler) durumları sürekli olarak izlenirken, sarf malzemeleri birden çok kez satın alınabilir. Tekrar test etmek için Play yönetim konsolunuza gitmeniz ve satışı iptal etmeniz / geri ödemeniz gerekir.


1
Ama mesele şu ki, bu "sahte" ürünler üzerinde herhangi bir "gücüm" yok ve gerçek satın alma olmadıkları için satış durumunu nerede değiştirebileceğimi bilmiyorum. Google doc android.test.purchased hakkında diyor ki: Eğer bu ürün kimliğine sahip bir In-app Fatura talepte, Google Play yanıt verir sanki başarıyla bir öğe satın aldı. Bu yüzden oldukça kafam karıştı: /
psykhi

Hala statik yanıt testi yapıyor musunuz? Öyleyse, gönderilecek statik yanıtı değiştirmeniz yeterlidir. "Kendi Ürün Kimliklerinizi Kullanarak Uygulama İçi Satın Alımları Test Etmek" gibi görünüyor, ancak bu, iptal edilebilir siparişlerle gerçek satın alımlar yapıyor.
addaon

Hala statik kimliklerle takıldım. Android.test.purchased ID ile bir uygulama içi satın alma işlemini test edebilmek istiyorum. Her zaman Google dokümanından anladığım kadarıyla çalışması gerektiğinde ilk seferinde çalıştı. Net olamadıysam özür dilerim!
psykhi

Yanlış yorumlamam, üzgünüm. Bu durumda ... bilmiyorum. Kesinlikle her seferinde başarıya dönmesi gerekiyor, gördüğünüz vakayı görmedim. Afedersiniz.
addaon

İyi bir uykudan sonra soruna tekrar bakmaya çalışacağım :) Yardımın için teşekkürler!
psykhi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.