Тест биллинга в приложении: android.test.purchased уже есть


122

В настоящее время я тестирую In-App Billing для будущего приложения, и после того, как я успешно «купил» тестовый элемент «android.test.purchased» в первый раз, теперь я получаю код ответа 7 каждый раз, когда пытаюсь купить его снова, Это означает, что этот предмет у меня уже есть.

12-15 23: 02: 14.149: E / IabHelper (19829): Ошибка биллинга в приложении: невозможно купить товар, реакция на ошибку: 7: Товар уже в собственности

Насколько я понимаю, эта покупка должна быть возможна всегда, верно? Чтобы разработчик мог протестировать свое приложение?

Если нет, как я могу «сбросить» его состояние на «не принадлежит»? Я использую служебный пакет из образца Google In-App Billing Sample.


1
мой набор - это тиски стихов .. мне нужно, чтобы сообщение уже было, но каждый раз его разрешают покупать
Sandeep P

Ответы:


109

Добавьте этот код в поток, чтобы инициировать запрос на потребление.

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

Здесь для проверки покупки PurchaseToken

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

И

if (response == 0)

тогда потребление успешное.

также не забудьте сделать mService общедоступным в

IabHelper.Java

тогда можно было бы получить доступ так:

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

2
Легенда, что это работает, @psykhi действительно должен был дать вам очки. Я пытался использовать его, но не мог вычислить токен покупки. Спасибо
Blundell

1
Спасибо! @prasharonnet
Y2i

1
Это огромная экономия времени. Отлично. Спасибо.
PrivusGuru

13
Что такое mService? mHelper? Но я не могу найти consumerPurchase ()
Bagusflyer

1
mService - это объект интерфейса IInAppBillingService.aidl, который связан с услугой покупки, инициированной для покупки inapp.
Аашутош Шарма,

93

Нет необходимости писать специальный код потребления. Просто используйте команду adb для очистки данных в Google Play Store:

adb shell pm clear com.android.vending

1
спасибо, что трюк сработал, мне просто нужно было очистить приложение, поэтому я сделал полный ответ. Для меня это правильный подход.
sivi 01

Это правильный подход для многих людей. Добавление кода в приложение и повторное развертывание занимает больше времени (каламбур).
Майкл Лаббе

9
Это хорошее решение для тестового устройства, но будьте осторожны: оно сбросит все ваши настройки в приложении Google Play Store. Поэтому я бы предпочел не делать это на своем личном устройстве.
racs

7
Нет! это плохая идея, вы потеряли покупку в приложении другого продукта и других приложений, хорошо, что вам нужно потреблять продукт, если вы хотите протестировать свою покупку в приложении, сценарий просто создает две вещи: одну для покупки, а другую для потребления, приобретенного пункт.
Рахул Мандалия

2
@RahulMandaliya: ваше приложение должно быть устойчивым к очисткам кеша с помощью API getPurchases (), чтобы знать, что уже было куплено.
mttmllns

66

Оказывается, элемент android.test.purchased ведет себя как обычный идентификатор. Это означает, что если вы хотите иметь возможность купить его снова, вы должны использовать его где-нибудь в своем коде. Я думаю, что документация Google вводит в заблуждение по этому поводу и что они должны добавить еще один статический идентификатор, который вы можете бесконечно покупать в тестовых целях.


Используйте вызов инвентаря, чтобы получить объект Purchase, а затем использовать его - это довольно легко, если вы его осмотрите.
slott

3
Посмотрите на ответ @mttmlins ниже или прочтите vvse.com/blog/blog/2016/08/26/…
Игорь

Не совсем верно, у меня есть случай, когда есть неиспользованный тестовый предмет, но я billingClient.queryPurchases()не возвращаю этот неиспользованный предмет, поэтому теперь я не могу потреблять предмет, потому что не могу purchaseTokenего получить,
Джемшит Искендеров

28

Версия в приложении 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);
        }
    }
};

Как картинка стоит тысячи слов, так и готовый рабочий кусок кода стоит тысячи слов ». Добавьте этот код в поток. , . '.
Androidcoder

11

Версия 3 - Самый быстрый способ решения : очистка кеша Google Play Store позволит снова сделать "android.test.purchased" доступным.


Разве это не повлияет на другие приложения, установленные в системе?
Игорь Ганапольский 01

1
@IgorGanapolsky, нет. Это коснется только смоделированных покупок. «Настоящие» покупки хранятся на сервере Google и не изменяются.
Денис

1
Я удалил данные приложения из Google Play, но это не сработало. Детали тестовой покупки все еще существуют.
Шрикар Редди

2
@Richard через "настройки / диспетчер приложений /" или перетащив значок магазина Google Play из меню на кнопку "информация" (вверху экрана). Наконец, просто нажмите кнопку «очистить кеш».
Денис

1
Лучший ответ для меня. Все остальные хороши, но это определенно самый быстрый способ решить
Игнасио Рода


9

Вот как мы можем потреблять Предмет

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

Сработало для меня - использовал android.test.purchaseв какой-то момент, что вызывало проблемы - задача инвентаризации в биллинге в приложении просто вызвала кучу ошибок и так и не была завершена. Выполнение этого как разового варианта очистило его, так что я мог возобновить использование моего фактического SKU и продолжить работу, как раньше. Спасибо
Джон

1
Отличный ответ. Работает со статическими ответами = до загрузки apk с включенным биллингом в приложениях в Google Play.
infero

Спасибо! Работал у меня.
AndroidMechanic - Viral Patel

6

На мой взгляд, если ваша программа не предназначена для использования элемента, вам не нужно настраивать код, чтобы очистить память внешнего поставщика. Это сделает ваш код более хрупким, и тогда вам придется потратить много времени на добавление и удаление кода, который не принадлежит вашему программному обеспечению, поэтому внедрять подобное решение - плохой дизайн.

Лучшее решение, которое помогло мне очистить android.test.purchased, было

adb uninstall com.yourapp.name

а потом

adb shell pm clear com.android.vending

Мне не нужно было снимать наличные и просматривать настройки моих приложений или изменять для этого код. Мне действительно нужно было добавить adb в переменные пути в системе Windows, что было довольно просто. Так что да, вам нужно использовать adb, который вам, вероятно, нужен в любом случае ..

Вы просто добавляете свой C: \ ... \ android-sdk \ platform-tools; в пути Windows в переменных среды, и я полагаю, что это довольно просто в Mac и Linux OS. Надеюсь, это поможет кому-то тратить на несколько дней меньше времени на внедрение Android в биллинг приложений.


uninstallне надо очищать android.test.purchased sku.
Игорь Ганапольский 01

4

Основная проблема в том, что вы должны потреблять android.test.purchased предмет. Но этот элемент не будет доступен в вашем инвентаре запроса, поэтому вы не сможете использовать его в обычном потоке.

Итак, если вы используете IabHelper в IabHelperклассе, вы можете временно изменитьIInAppBillingService mService на общедоступный, чтобы он был доступен из вашего IabHelper.

Тогда в своем классе вы можете потреблять вот так:

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

В случае успеха ответ будет 0.

Надеюсь это поможет.


Касательная: можно ли вернуть деньги за управляемый элемент (с тестовой учетной записью - похоже, это не отображается на панели управления)?
Эд Ли

Можно позвонить consumeAsync()на android.test.purchased . С этим нет проблем.
Игорь Ганапольский 01

Для простого теста лучше всего использовать IabHelper. Помог мне.
Rúben

2

В целях тестирования я также предлагаю вам вставить фрагмент кода, который будет очищать все продукты, которые вы купили, перед вызовом метода, который инициализирует поток покупок gp. Это особенно удобно, когда вы тестируете в данный момент только один элемент. Например, вот так:

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 и откройте вкладку «Управление заказами». Там вы можете вернуть / отменить тестовые покупки.


1

Если вы находитесь в тестовой среде

1) В случае покупки android.test.purchased я могу сбросить фальшивый платеж, перезапустив устройство Android (израсходованный инвентарь).

2) В InApp util есть файл под названием Security.java, сделайте его следующим образом для временного использования. Поскольку тестовый платеж (поддельный) всегда возвращает false из-за исключения безопасности.

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

Затем в вашем OnIabPurchaseFinishedListener вызовите 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);
        }


    }
};

Consume Listener - это

    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

В моем случае оказалось, что Google не регистрирует покупку товара. Скорее, локальная копия Сервисов Google Play кеширует покупку. Таким образом, когда на том же устройстве будет сделан второй запрос, android.test.purchased already ownedпоявится. Однако использование другого устройства или сброс устройства очищает кеш и позволяет повторить покупку.


-1

В моем случае мне просто нужно было очистить кеш приложений. После очистки кеша я снова смог инициировать процесс покупки.

Со своего устройства (4.4.2) я перешел в «Настройки-> Диспетчер приложений». Затем я выбрал приложение на вкладке «ЗАГРУЖЕННЫЕ», а затем «Очистить кеш».


-2

В этом разница между расходными и непотребляемыми предметами; Состояние непотребляемых предметов (с чем, похоже, вы здесь имеете дело) постоянно отслеживается, в то время как расходные предметы можно покупать несколько раз. Вам нужно будет зайти в консоль управления Play и отменить / вернуть деньги за продажу, чтобы протестировать ее снова.


1
Но дело в том, что у меня нет «власти» над этими «фальшивыми» предметами, и я не вижу, где я могу изменить статус продажи, поскольку они не являются настоящими покупками. В документе google говорится о android.test.purchased: когда вы делаете запрос на выставление счетов в приложении с этим идентификатором продукта, Google Play отвечает так, как если бы вы успешно приобрели товар. Так что я очень запутался: /
psykhi

Вы все еще проводите статическое тестирование ответа? Если это так, вам просто нужно изменить, какой статический ответ отправляется. Похоже, вы подошли к «Тестированию покупок в приложении с использованием собственных идентификаторов продуктов», в котором совершаются реальные покупки с отменяемыми заказами.
addaon

Я все еще застрял со статическими идентификаторами. Я бы хотел иметь возможность протестировать покупку в приложении с идентификатором android.test.purchased. Просто это сработало в первый раз, хотя должно всегда работать, насколько я понимаю из документа Google. Извините, если я не понял!
Psykhi

Мое неверное толкование, извините. В таком случае ... я не знаю. Он определенно должен возвращать успех каждый раз, я не видел случая, который вы видите. Сожалею.
addaon

Постараюсь еще раз взглянуть на проблему после хорошего сна :) Спасибо за помощь!
Psykhi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.