android in-app purchases 7 Аппсторов за полчаса Настя Каримова...

31
Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

Upload: oliver-childres

Post on 31-Mar-2015

233 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

Android In-App Purchases7 Аппсторов за полчаса

Настя КаримоваРазработчик мобильных приложений

Page 2: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

Топ приложений в Google Play

Page 3: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

Рекламные баннеры

Page 4: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

Покупки внутри приложений

Page 5: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

5

контентфункциональностьсервисы

Можно продавать

Page 6: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

6

сonsumable (заклинания, жизни, время) non-consumable (уровни, текст книги) subscriptions (подписки на контент)

Виды инаппов

Page 7: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

7

Вот так выглядит инапп

com.game.SKU_THE_BEST_SWORD_EVER

Page 8: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

8

Page 9: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

9

<uses-permission android:name="com.android.vending.BILLING"/>

Permission

Page 10: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

10

IabHelper helper = new IabHelper(context, "your_base_64_public_key");helper.startSetup(new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { if (result.isSuccess()) { //query inventory } else { complain("Billing is not supported."); } } });

Настройка

Page 11: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

11

helper.queryInventoryAsync(true, new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inventory) { if (result.isFailure()) { complain(String.format("queryInventory failed:%s", result)); } else { //consume if not consumed //update UI } }});

Запрашиваем инвентарь

Page 12: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

12

final Purchase tipPurchase = inventory.getPurchase(IN_APP_SKU_TIP);if (tipPurchase != null) { helper.consumeAsync(tipPurchase, new IabHelper.OnConsumeFinishedListener() { @Override public void onConsumeFinished(Purchase purchase, IabResult result) { if (result.isSuccess()) { if (purchase.getSku().equals(IN_APP_SKU_TIP)) { //process it //update UI } } } });}

Выполняем consume

Page 13: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

13

helper.launchPurchaseFlow(this, sku, REQUEST_CODE_PURCHASE_CODE, new IabHelper.OnIabPurchaseFinishedListener() { @Override public void onIabPurchaseFinished(IabResult result, Purchase info) { if (result.isSuccess() && info.getSku().equals(IN_APP_SKU_TIP)) {

//consume //update UI

} }});

// your code here@Overrideprotected void onActivityResult(int reqCode, int resCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);

helper.handleActivityResult(requestCode, resultCode, data);}

Покупка

Page 14: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

14

Аппсторы

Page 15: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

15

Page 16: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

16

<application>...<receiver android:name = "com.amazon.inapp.purchasing.ResponseReceiver" >

<intent-filter> <action android:name = "com.amazon.inapp.purchasing.NOTIFY" android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY" /></intent-filter></receiver>...</application>

В манифесте

Page 17: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

17

public class MyPurchasingObserver extends BasePurchasingObserver {private static final String TAG = "IAPPurchasingObserver"; public MyPurchasingObserver(Activity iapActivity) { super(iapActivity);} public void onSdkAvailable(final boolean isSandboxMode) {}public void onGetUserIdResponse(final GetUserIdResponse response) {}public void onItemDataResponse(final ItemDataResponse response) {}public void onPurchaseResponse(final PurchaseResponse response) {}public void onPurchaseUpdatesResponse( final PurchaseUpdatesResponse response) {}}

Purchasing observer

Page 18: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

18

public class IAPActivity extends Activity {... protected void onCreate(Bundle savedInstanceState) { ... PurchasingManager.registerObserver(new MyPurchasingObserver(this)); } ... }

Регистрируем observer

Page 19: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

19

PurchasingManager.initiatePurchaseUpdatesRequest(getPersistedOffset());

public class MyPurchasingObserver extends BasePurchasingObserver {... public void onPurchaseUpdatesResponse( final PurchaseUpdatesResponse response) {

// No implementation required when dealing solely // with consumables.

}...}

Запрашиваем инвентарь

Page 20: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

20

public class IAPActivity extends Activity { // ... private void initiatePurchase() { String requestId = PurchasingManager.initiatePurchaseRequest ("com.amazon.example.iap.consumable"); } // ...}

public class MyPurchasingObserver extends BasePurchasingObserver {... public void onPurchaseResponse(PurchaseResponse response) { final PurchaseRequestStatus status = response .getPurchaseRequestStatus(); if (status == PurchaseResponse.PurchaseRequestStatus.SUCCESSFUL) { } }...}

Процесс покупки

Page 21: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

21

Page 22: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

22

<!--all stores--><uses-permission android:name="android.permission.INTERNET"/><!--Google Play--><uses-permission android:name="com.android.vending.BILLING" /><!--Amazon--><uses-permission android:name="com.sec.android.iap.permission.BILLING" /><!--Samsung Apps--><uses-permission android:name="com.sec.android.iap.permission.BILLING" /><!--Open Store--><uses-permission android:name="org.onepf.openiab.permission.BILLING" /><!--T-Store and Fortumo--><uses-permission android:name="android.permission.RECEIVE_SMS"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.READ_PHONE_STATE" /><!--T-Store--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="com.tmoney.vending.INBILLING" /><permission android:name="com.tmoney.vending.INBILLING" /><!--Fortumo--><uses-permission android:name="android.permission.SEND_SMS" />

Permissions

Page 23: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

23

Маппинг SKUOpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_AMAZON, "org.onepf.trivialdrive.amazon.premium");

OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_TSTORE, "tstore_sku_premium");

OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_SAMSUNG, "100000100696/000001003746");

OpenIabHelper.mapSku(SKU_PREMIUM, "com.yandex.store", "org.onepf.trivialdrive.premium");

OpenIabHelper.mapSku(SKU_GAS, OpenIabHelper.NAME_AMAZON, "org.onepf.trivialdrive.amazon.gas");

OpenIabHelper.mapSku(SKU_GAS, OpenIabHelper.NAME_SAMSUNG, "100000100696/000001003744");

OpenIabHelper.mapSku(SKU_GAS, "com.yandex.store", "org.onepf.trivialdrive.gas");

OpenIabHelper.mapSku(SKU_INFINITE_GAS, OpenIabHelper.NAME_AMAZON, "org.onepf.trivialdrive.amazon.infinite_gas");

OpenIabHelper.mapSku(SKU_INFINITE_GAS, OpenIabHelper.NAME_SAMSUNG, "100000100696/000001003747");

OpenIabHelper.mapSku(SKU_INFINITE_GAS, "com.yandex.store", "org.onepf.trivialdrive.infinite_gas");

Page 24: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

24

OpenIabHelper.Options options = new OpenIabHelper.Options();Map<String, String> storeKeys = new HashMap<String, String>();storeKeys.put(OpenIabHelper.NAME_GOOGLE, googleBase64EncodedPublicKey);

/* storeKeys.put(OpenIabHelper.NAME_AMAZON, "Unavailable. Amazon doesn't support RSA verification. So this mapping is not needed"); */

/* storeKeys.put(OpenIabHelper.NAME_SAMSUNG,"Unavailable. SamsungApps doesn't support RSA verification. So this mapping is not needed"); */

storeKeys.put(OpenIabHelper.NAME_YANDEX, YANDEX_PUBLIC_KEY);

options.storeKeys = storeKeys; options.checkInventory = true; options.prefferedStoreNames = ... options.availableStores = ...

Опции

Page 25: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

25

OpenIabHelper helper = new OpenIabHelper(context, options);helper.startSetup(new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { if (result.isSuccess()) { //query inventory } else { complain("Billing is not supported."); } } });

Настройка

Page 26: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

26

helper.queryInventoryAsync(true, new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inventory) { if (result.isFailure()) { complain(String.format("queryInventory failed: %s”, result)); } else { //consume if not consumed //update UI } }});

Запрашиваем инвентарь

Page 27: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

27

final Purchase tipPurchase = inventory.getPurchase(IN_APP_SKU_TIP);

if (tipPurchase != null) {

helper.consumeAsync(tipPurchase, newIabHelper.OnConsumeFinishedListener() {

@Override public void onConsumeFinished(Purchase purchase, IabResult result) {

if (result.isSuccess()) { if (purchase.getSku().equals(IN_APP_SKU_TIP)) { //process it //update UI } } } });}

Выполняем consume

Page 28: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

28

helper.launchPurchaseFlow(this, sku, REQUEST_CODE_PURCHASE_CODE, new IabHelper.OnIabPurchaseFinishedListener() { @Override public void onIabPurchaseFinished(IabResult result, Purchase info) {

if (result.isSuccess() && info.getSku().equals(IN_APP_SKU_TIP)) {

//consume //update UI

} }});

// your code here

@Overrideprotected void onActivityResult(int reqCode, int resCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);

helper.handleActivityResult(requestCode, resultCode, data);}

Покупка

Page 29: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

29

Верификация Server-2-Server

Page 30: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

30

public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {

if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) || TextUtils.isEmpty(signature)) { Log.e(TAG, "Purchase verification failed: missing data."); return false; } PublicKey key = Security.generatePublicKey(base64PublicKey); return Security.verify(key, signedData, signature); }

// Unique OpenIAB feature =)

Options opts = new Options();opts.verifyMode = Options.VERIFY_SKIP;

mHelper = new OpenIabHelper(context, opts);

Код верификации

Page 31: Android In-App Purchases 7 Аппсторов за полчаса Настя Каримова Разработчик мобильных приложений

31

One PlatformFoundation

www.onepf.org

[email protected]

github.com/onepf/OpenIABgithub.com/onepf/AppDF