Android In-app purchasing: платное отключение рекламы в своём приложении

Много раз уже просили написать статью о том, как в приложении реализовать платное отключение рекламы. Вообще, реализовать рекламу легко, по In-app так же есть куча информации в официальной документации. Ну, если кому-то всё же статья пригодится, то хорошо.

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

В данной статье рассмотрю как можно использовать In-App Purchase для отключения рекламы в своём приложении.

Реклама в приложении

В принципе, можно взять любую площадку. Возьмём, к примеру AdMob. Я для удобства обычно подобные вещи в обёртки запихиваю, чтобы при смене площадки, если потребуется, почти ничего не пришлось менять. Обёртки для рекламной площадки должны реализовывать интерфейс:

public interface AdsControllerBase {public void createView( RelativeLayout layout);public void show(boolean show);public void onStart();public void onDestroy();public void onResume();public void onStop();}

Тогда обёртка для AdMob будет выглядеть примерно так:

public class AdMobController implements AdsControllerBase, AdListener {private static final String ADMOB_ID = "ваш_идентификатор_из_AdMob";private static final int REQUEST_TIMEOUT = 30000;private AdView adView;private Context c;private long last;public AdMobController(Context activity, RelativeLayout layout) {this.c = activity;createView(layout);last = System.currentTimeMillis() - REQUEST_TIMEOUT;}public void createView(RelativeLayout layout) {if(PreferencesHelper.isAdsDisabled()) return;adView = new AdView((Activity) c, AdSize.BANNER, ADMOB_ID);RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);adParams.addRule(RelativeLayout.CENTER_HORIZONTAL);adView.setAdListener(this);layout.addView(adView, adParams);adView.loadAd(new AdRequest()); }// обновляем рекламу не чаще, чем раз в 30 секундpublic void show(boolean show) {if(adView == null) return;adView.setVisibility((show) ? View.VISIBLE : View.GONE);if (show && (System.currentTimeMillis() - last > REQUEST_TIMEOUT)) {last = System.currentTimeMillis();adView.loadAd(new AdRequest());}}@Overridepublic void onReceiveAd(Ad ad) {}@Overridepublic void onFailedToReceiveAd(Ad ad, AdRequest.ErrorCode error) {}@Overridepublic void onPresentScreen(Ad ad) {}@Overridepublic void onDismissScreen(Ad ad) {}@Overridepublic void onLeaveApplication(Ad ad) {}@Overridepublic void onStart() {}@Overridepublic void onDestroy() {}@Overridepublic void onResume() {}@Overridepublic void onStop() {}}

Тогда инициализация рекламы будет такой:

AdsControllerBase ads = new AdMobController(this, layout);

При такой реализации в случае смены площадки, мы просто создадим инстанс другого класса. Для работы вам нужен лишь ID_приложения. который получите после создания в приложения в админке Admob.

In-app purchasing или внутренние платежи в приложениях

Для того, чтобы работать с системой покупок необходим файл IMarketBillingService.aidl. Лежит он в /user/android-sdk-linux/extras/google/play_billing директории с SDK. Положить файлик надо в com.android.vending.billing пакет вашего приложения.

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

Для работы необходимо добавить разрешение в AndroidManifest.xml:<uses-permission android:name="com.android.vending.BILLING"/>.

Очень помогает официальная документация и пример из SDK.

Необходимо определить ключик в приложении — PublicKey, полученный при регистрации аккаунта на Android Market

Определяем IabHelper и инициализируем. Если удачно, то пытаемся восстановить покупки.

// id вашей покупки из админки в Google Playstatic final String SKU_ADS_DISABLE = "com.ads.disable";IabHelper mHelper;private void billingInit() {mHelper = new IabHelper(this, BASE64_PUBLIC_KEY);// включаем дебагинг (в релизной версии ОБЯЗАТЕЛЬНО выставьте в false)mHelper.enableDebugLogging(true);// инициализируем; запрос асинхронен // будет вызван, когда инициализация завершитсяmHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {public void onIabSetupFinished(IabResult result) {if (!result.isSuccess()) {return;}// чекаем уже купленноеmHelper. queryInventoryAsync(mGotInventoryListener);}});}

mGotInventoryListener — слушатель для восстановления покупок.

// Слушатель для востановителя покупок.IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {private static final String TAG = "QueryInventoryFinishedListener";public void onQueryInventoryFinished(IabResult result,Inventory inventory) {LOG.d(TAG, "Query inventory finished.");if (result.isFailure()) {LOG.d(TAG, "Failed to query inventory: " + result);return;}LOG.d(TAG, "Query inventory was successful.");Purchase purchase = inventory.getPurchase(SKU_ADS_DISABLE);PreferencesHelper.savePurchase(context,PreferencesHelper.Purchase.DISABLE_ADS,purchase != null && verifyDeveloperPayload(purchase));ads.show(!PreferencesHelper.isAdsDisabled());}};

Теперь надо, собственно, саму покупку реализовать:

private void buy(){if(!PreferencesHelper.isAdsDisabled()){String payload = ""; mHelper.launchPurchaseFlow(this, SKU_ADS_DISABLE, RC_REQUEST,mPurchaseFinishedListener, payload);}}

SKU_ADS_DISABLE — идентификатор товара, который вы создали в адмике Google Play. mPurchaseFinishedListener — слушатель:

// слушатель завершения покупкиIabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {public void onIabPurchaseFinished(IabResult result, Purchase purchase) {if (result.isFailure()) {return;}if (!verifyDeveloperPayload(purchase)) {return;}if (purchase.getSku().equals(SKU_ADS_DISABLE)) {Toast.makeText(getApplicationContext(), "Purchase for disabling ads done.", Toast.LENGTH_SHORT);// сохраняем в настройках, что отключили рекламуPreferencesHelper.savePurchase(context,PreferencesHelper.Purchase.DISABLE_ADS,true);// отключаем рекламуads.show(!PreferencesHelper.isAdsDisabled());}}};

Стоит отдельно поговорить о методе по верификации:

boolean verifyDeveloperPayload(Purchase p) {String payload = p.getDeveloperPayload();return true;}

Сейчас нет никакой проверки покупок, но в реальном приложении вы должны сверять полученные данные с той сгенерированой строкой, что вы отправили в запросе на покупку. Проверять это надо на своём стороннем сервере. Для обычно приложения или офф-лайн игры это может и не критично, но для он-лайн игры это очень важно.

В принципе всё, теперь при запуске приложения просиходит проверка настроек (куда мы сохранили, что отключили рекламу):

PreferencesHelper.loadSettings(this);

После чего реклама уже не будет показываться.

Тестирование покупок

Сейчас довольно удобно тестировать своё приложение. Можно залить .apk как альфа/бета версию и опубликовать. При этом можно назначить группу в Google+, которая будет иметь возможность к тестированию. Если вы публикуете альфа или бета версию приложения, то в маркете она не появится, иметь доступ будет только эта группа.

Тестеры смогут осуществлять покупки. Деньги будут списываться без комиссии и будут возвращены после 15 минут после покупки. Так что, не беспокойтесь. Вот только у вас не получится протестировать приложение, если ваш аккаунт на устройстве и аккаунт издателя один и тот же =/

Полностью рабочий пример можете форкнуть с гитхаба.

Android In-app purchasing: платное отключение рекламы в своём приложении: 8 комментариев

  1. Revan

    Помогите !Как сделать «Android In-app purchasing: платное отключение рекламы в своём приложении» но с использованием xml .

      1. Revan

        стандартно у меня все экраны так сказать setContentView(R.layout.name); то есть все кнопки все содержится в xml ,а не в LayoutParams

Добавить комментарий для Revan Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *