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

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

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 будет выглядеть примерно так:

Обёртка для 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()); 		} 	}  	@Override 	public void onReceiveAd(Ad ad) {}  	@Override 	public void onFailedToReceiveAd(Ad ad, AdRequest.ErrorCode error) {}  	@Override 	public void onPresentScreen(Ad ad) {}  	@Override 	public void onDismissScreen(Ad ad) {}  	@Override 	public void onLeaveApplication(Ad ad) {}  	@Override 	public void onStart() {}  	@Override 	public void onDestroy() {}  	@Override 	public void onResume() {}  	@Override 	public 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 Play static 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.");  			/* 			 * Проверяются покупки.  			 * Обратите внимание, что надо проверить каждую покупку, чтобы убедиться, что всё норм!  			 * см. verifyDeveloperPayload(). 			 */ 			 			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()){ 			/* для безопасности сгенерьте payload для верификации. В данном примере просто пустая строка юзается. 			 * Но в реальном приложение подходить к этому шагу с умом. */ 		    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(); 		/* 		 * TODO: здесь необходимо свою верификацию реализовать 		 * Хорошо бы ещё с использованием собственного стороннего сервера. 		 */  		return true; 	} 

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

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

PreferencesHelper.loadSettings(this); 

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

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

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

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

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

ссылка на оригинал статьи http://habrahabr.ru/post/203368/

Добавить комментарий

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