Биллинг в приложении Android, не расходные материалы

Я внедряю биллинг в приложении, где пользователь может покупать доступ к премиум-контенту. Это типичные не расходные материалы. (Допустим, премиум-контент - это дополнительные вопросы или категории в приложении для вопросов)

Я использовал этот учебник для создания первой версии . Проблема в том, как реализовать нерасходуемую часть ..

Как я узнаю, что пользователь купил премиум-контент? Одно из решений, о котором я думаю, - это иметь столбец в моей таблице вопросов, который изначально равен «0». Когда пользователь покупает премиум-доступ, в этом столбце устанавливается значение «1». Это способ пойти?

Где в моем коде я получу сообщение от API биллинга о том, что контент уже куплен? (Если это..)

Мой код .. (Из учебника "купите возможность нажать кнопку")

public class BuyExtras extends Activity {

private static final String TAG = "inAppBilling";
static final String ITEM_SKU = "android.test.purchased";
IabHelper mHelper;
private Button clickButton;
private Button buyButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "onCreate CALLED");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_buy_extras);


    buyButton = (Button)findViewById(R.id.buyButton);
    clickButton = (Button)findViewById(R.id.clickButton);   
    clickButton.setEnabled(false);



    String base64EncodedPublicKey = 
            "<myKey>";

    mHelper = new IabHelper(this, base64EncodedPublicKey);

    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        public void onIabSetupFinished(IabResult result) 
        {
            if (!result.isSuccess()) {
                Log.d(TAG, "In-app Billing setup failed: " + 
                        result);
            } else {             
                Log.d(TAG, "In-app Billing is set up OK");
            }
        }
    });


}

public void buyClick(View view) {
    mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001, mPurchaseFinishedListener, "mypurchasetoken");
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
    if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {     
        super.onActivityResult(requestCode, resultCode, data);
    }
}


IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) 
    {
        if (result.isFailure()) {
            // Handle error
            return;
        }      
        else if (purchase.getSku().equals(ITEM_SKU)) {
            consumeItem();
            buyButton.setEnabled(false);
        }

    }
};

public void consumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}

IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        if (result.isFailure()) {
            // Handle failure
        } else {
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU), mConsumeFinishedListener);
        }
    }
};


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

        if (result.isSuccess()) {         
            clickButton.setEnabled(true);
        } else {
            // handle error
        }
    }
};

public void buttonClicked (View view)
{
    clickButton.setEnabled(false);
    buyButton.setEnabled(true);
}


@Override
public void onDestroy() {
    super.onDestroy();
    if (mHelper != null) mHelper.dispose();
    mHelper = null;
}

}

Я прочитал этот вопрос, указывающий на то, что мне не следует вызывать

mHelper.consumeAsync (покупка, mConsumeFinishedListener);

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


person EirikO    schedule 29.04.2014    source источник
comment
Если вы не потребляете его, то попытка второй покупки вызовет исключение, что предмет уже был куплен. Это должно решить проблему за вас. Попробуйте сами.   -  person 323go    schedule 29.04.2014
comment
Было бы это в onIabPurchaseFinished (result.isFailure ())?   -  person EirikO    schedule 29.04.2014


Ответы (1)


Если вы не хотите потреблять, не используйте Consumer Async.

 @Override
public void onQueryInventoryFinished(IabResult result, Inventory inv)
{
    if (result.isFailure())
    {
        Log.e(TAG, "In-app Billing query failed: " + result);
        return;
    } else
    {
        boolean hasPurchased_ITEM_SKU_PURCHASE_1 = inv.hasPurchase(ITEM_SKU_PURCHASE_1);
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putBoolean(KEY_PREF_PURCHASE_1_AVAILABLE, !hasPurchased_ITEM_SKU_PURCHASE_1);
        editor.commit();

        // You can update your UI here, ie. Buy buttons.
    }
}

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

     boolean hasPurchased_ITEM_SKU_PURCHASE_1 = inv.hasPurchase(ITEM_SKU_PURCHASE_1);

Выполните синхронизацию запросов в настройках IAP и соответствующим образом обновите пользовательский интерфейс.

 mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
    public void onIabSetupFinished(IabResult result) 
    {
        if (!result.isSuccess()) {
            Log.d(TAG, "In-app Billing setup failed: " + 
                    result);
        } else {             
              mHelper.queryInventoryAsync(mReceivedInventoryListener);
            Log.d(TAG, "In-app Billing is set up OK");
        }
    }
 });
person uDevel    schedule 29.04.2014
comment
Разве ваше предложение кода не следует помещать в onIabPurchaseFinished () вместо onQueryInventoryFinished ()? Я получаю сообщение об ошибке (элемент уже принадлежит) в этой функции, которая вызывается перед onQueryInventroyFinished () ... - person EirikO; 29.04.2014
comment
Нет, вам следует выполнить проверку запроса inv в onCreate действия или фрагмента, а затем соответствующим образом изменить свой пользовательский интерфейс. Пользователь никогда не должен иметь возможность снова купить тот же элемент из вашего пользовательского интерфейса, поэтому он никогда не должен начинать с onIabPurchaseFinished () для того же элемента. - person uDevel; 29.04.2014
comment
Ненавижу, когда люди делают это без объяснения причин. Вот возьми +1 голос;) - person Jakub Turcovsky; 24.02.2015