1 / 31

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

Android In-App Purchases 7 Аппсторов за полчаса. Настя Каримова Разработчик мобильных приложений. Топ приложений в Google Play. Рекламные баннеры . Покупки внутри приложений. к онтент ф ункциональность сервисы. Можно продавать. с onsumable (заклинания, жизни, время)

bobby
Télécharger la présentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

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

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

  5. контент • функциональность • сервисы • Можно продавать

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

  7. Вот так выглядит инапп com.game.SKU_THE_BEST_SWORD_EVER

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

  9. IabHelperhelper = 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."); } } }); Настройка

  10. helper.queryInventoryAsync(true, new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResultresult, Inventory inventory) { if (result.isFailure()) { complain(String.format("queryInventory failed:%s", result)); } else { //consume if not consumed //update UI } } }); Запрашиваем инвентарь

  11. final Purchase tipPurchase = inventory.getPurchase(IN_APP_SKU_TIP); if (tipPurchase != null) { helper.consumeAsync(tipPurchase, new IabHelper.OnConsumeFinishedListener() { @Override public void onConsumeFinished(Purchase purchase, IabResultresult) { if (result.isSuccess()) { if (purchase.getSku().equals(IN_APP_SKU_TIP)) { //process it //update UI } } } }); } Выполняем consume

  12. 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 @Override protected void onActivityResult(intreqCode, intresCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); helper.handleActivityResult(requestCode, resultCode, data); } Покупка

  13. Аппсторы

  14. <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> В манифесте

  15. public class MyPurchasingObserver extends BasePurchasingObserver { private static final String TAG = "IAPPurchasingObserver"; public MyPurchasingObserver(Activity iapActivity) { super(iapActivity); } public void onSdkAvailable(final booleanisSandboxMode) {} 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

  16. public class IAPActivity extends Activity { ... protected void onCreate(Bundle savedInstanceState) { ... PurchasingManager.registerObserver(new MyPurchasingObserver(this)); } ... } Регистрируем observer

  17. PurchasingManager.initiatePurchaseUpdatesRequest(getPersistedOffset());PurchasingManager.initiatePurchaseUpdatesRequest(getPersistedOffset()); public class MyPurchasingObserver extends BasePurchasingObserver { ... public void onPurchaseUpdatesResponse( final PurchaseUpdatesResponse response) { // No implementation required when dealing solely // with consumables. } ... } Запрашиваем инвентарь

  18. 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) { } } ... } Процесс покупки

  19. <!--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

  20. МаппингSKU OpenIabHelper.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");

  21. 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 = ... Опции

  22. OpenIabHelperhelper = 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."); } } }); Настройка

  23. helper.queryInventoryAsync(true, new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResultresult, Inventory inventory) { if (result.isFailure()) { complain(String.format("queryInventory failed: %s”, result)); } else { //consume if not consumed //update UI } } }); Запрашиваем инвентарь

  24. final Purchase tipPurchase = inventory.getPurchase(IN_APP_SKU_TIP); if (tipPurchase != null) { helper.consumeAsync(tipPurchase, newIabHelper.OnConsumeFinishedListener() { @Override public void onConsumeFinished(Purchase purchase, IabResultresult) { if (result.isSuccess()) { if (purchase.getSku().equals(IN_APP_SKU_TIP)) { //process it //update UI } } } }); } Выполняем consume

  25. 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 @Override protected void onActivityResult(intreqCode, intresCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); helper.handleActivityResult(requestCode, resultCode, data); } Покупка

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

  27. public static booleanverifyPurchase(String base64PublicKey, String signedData, String signature) { if (TextUtils.isEmpty(signedData) ||TextUtils.isEmpty(base64PublicKey) || TextUtils.isEmpty(signature)) { Log.e(TAG, "Purchaseverificationfailed: missing data."); return false; } PublicKeykey = Security.generatePublicKey(base64PublicKey); returnSecurity.verify(key, signedData, signature); } // Unique OpenIAB feature =) Options opts = new Options(); opts.verifyMode = Options.VERIFY_SKIP; mHelper = new OpenIabHelper(context, opts); Код верификации

  28. One Platform Foundation www.onepf.org akarimova@onepf.org github.com/onepf/OpenIAB github.com/onepf/AppDF

More Related