13 July 2011

Платное и бесплатное приложения: два в одном

Development for Android
Tutorial


О том, как непросто создать приложение с поддержкой In-App Purchase на хабре уже рассказывали (здесь и здесь), — слишком много кода для такой простой функциональности.

Даже поддержка оплаты через PayPal внедряется намного проще.

Но благодаря Robot Media SL и open-source библиотеки Android Billing Library, наша жизнь упрощается. Намного упрощается.


Рассмотрим пример как может выглядеть приложение, в котором есть платная функция — Убрать рекламу.

Прежде всего, Activity, в которой будет использована функция оплаты, должна расширять AbstractBillingActivity. В моем случае кнопка была добавлена в Настройки, потому пришлось чуть поправить этот класс, чтоб он сам расширял не Activity, а PreferenceActivity.

Сам код выглядит следующим образом:
public class Preferences extends AbstractBillingActivity {
public static final String ANDROID_MARKET_ITEM = "my_managed_item_id"; 
private boolean billingSupported = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ...
        Preference buyPref = (Preference) findPreference("pref_billing_buy");
        buyPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            // при нажатии на кнопку Убрать рекламу в настройках 
            public boolean onPreferenceClick(Preference preference) {   
                // проверяем поддерживается ли покупка в приложениях
                if (checkBillingSupported() != BillingStatus.SUPPORTED) {
                    // показываем сообщение, что покупка не поддерживается
                    showDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
                } else {
                    // проверяем не купил ли пользователь уже нашу опцию
                    Boolean purchased = BillingController.isPurchased(getApplicationContext(), ANDROID_MARKET_ITEM);
                    if (!purchased) {
                        // если не купил (или мы просто об этом пока не знаем? пользователь удалял 
                        // приложение со всем данными?), то пытаемся восстановить транзакции
                        restoreTransactions();
                        // следующая строка (проверка еще раз не купил ли пользователь приложение) -
                        // не очень правильный подход - вызвав restoreTransactions, 
                        // ответ мы получим не сразу
                        purchased = BillingController.isPurchased(getApplicationContext(), ANDROID_MARKET_ITEM);
                        if (!purchased) {
                            // наконец, показываем пользователю стандартное окно для покупки опции
                            requestPurchase(ANDROID_MARKET_ITEM);
                        }
                    }
                }
                return true;
            }
        });

    @Override
    public void onBillingChecked(boolean supported) {
        billingSupported = supported;
    }

    @Override
    public void onPurchaseCancelled(String itemId) {
        Log.i(TAG, "Transaction has been cancelled: "+itemId);
    }

    // пользователь купил приложение, тут можно сделать нужные изменения в UI
    @Override
    public void onPurchaseExecuted(String itemId) {     
        Log.i(TAG, "User bought ad-free version: "+itemId);
        CheckBoxPreference buyPref = (CheckBoxPreference) findPreference("pref_billing_buy");
        buyPref.setEnabled(false);
    }

    @Override
    public void onPurchaseRefunded(String itemId) {
        Log.i(TAG, "Transaction has been refunded: "+itemId);       
    }
 
    // библиотека сама шифрует наши данные, задаем здесь шифр
    @Override
    public byte[] getObfuscationSalt() {
        return new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
    }

    // тут нужно вернуть ваш ключ
    @Override
    public String getPublicKey() {
        return "my_key_is_here";
    }


Просто? Очень просто.

Ну и на всякий случай опубликую свой код, чтоб правильно убрать рекламу (в моем случае — AdMob), чтоб она не просто была скрыта, но и не скачивалась:
Boolean purchased = BillingController.isPurchased(getApplicationContext(), Preferences.ANDROID_MARKET_ITEM);
if (purchased) {
        LinearLayout adContainer = (LinearLayout) findViewById(R.id.bridges_list);
        View admobAds = (View) findViewById(R.id.adView);
        adContainer.removeView(admobAds);
}


Автор активно развивает библиотеку, прислушивается к пожеланиям, совсем недавно опубликовал исходники приложения с примером использования библиотеки.
Tags:in-app billingin-app purchasesandroidandroid development
Hubs: Development for Android
+41
11.5k 144
Comments 18
Top of the last 24 hours