Google play内购 Iab

(原文地址:http://blog.csdn.net/yupu56/article/details/49452107)


Google Play 内购 In-App-Billing在Android项目或者Cocos2dx/Unity项目中的集成.

最近在做一个游戏的海外版,需要加内购,碰到一些坑,这里记录下来,希望能对大家有个帮助。


参考教程:

Google Play In-app Billing官方教程
Google Play In-app Billing 踩过的那些坑
StackOverflow 论坛
Google Play 内购In-app-billing 总结~

开发者需要做的准备:


1.翻墙Android手机和电脑。

2.Google play 后台应用,并且把内购项目创建好并发布成功。能够得到内购产品的SKU即ProductID,和项目64位的秘钥。

3.内购产品的说明:

a.产品的id是唯一的字符串定义,比如com.engine.produce01,后台添加产品后需要激活。

b.In-app Billing 的 API 有个 v2 版本和 v3 版本,v2 版本已经不支持了,直接整 v3 版本的吧,Google Play 没有可重购买商品这个概念,所有的“商品/充值档”用户成功购买过一次之后就不允许再次购买了。所以为了实现像应用内支付充值这种可重复购买的“商品/充值档”,Google Play 提供了一个“消耗”借口(Consuming In-app Products)。用户购买完商品后,调一下“消耗”接口,这样用户下次就可以继续购买了。


使用IAB的流程:


1.首先确定你的SKU和Request值(随便填)


[java]  view plain  copy
  1. <pre name="code" class="java">static final String SKU_PACKAGE1 = "android.test.purchased";  
  2. static final String SKU_PACKAGE2 = "cinderella_product02";  
  3. static final String SKU_PACKAGE3 = "cinderella_infinite";  

 
 

[java]  view plain  copy
  1. // (arbitrary) request code for the purchase flow  
  2. static final int RC_REQUEST = 10001;  

2.IabHelper类初始化方法,这里的base64EncodedPublicKey是googleplay后台的发布产品的时候生成提供的


[java]  view plain  copy
  1. mHelper=new IabHelper(this, base64EncodedPublicKey);  

3.startSetup 的操作是检查是否有权限和连接到Google Billing service是否成功.


这里回调的操作是如果成功,调用queryInventoryAsync查看产品id是否可以使用,查询完成后会调用IabHelper.QueryInventoryFinishedListener 这个回调接口进行通知,在这个接口中可以获取商品的详细信息SkuDetails和Purchase信息。

[java]  view plain  copy
  1. mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {  
  2.     public void onIabSetupFinished(IabResult result) {  
  3.         Log.d(TAG, "Setup finished.");  
  4.   
  5.         if (!result.isSuccess()) {  
  6.             // Oh noes, there was a problem.  
  7.             complain("Problem setting up in-app billing: " + result);  
  8.             return;  
  9.         }  
  10.         // Have we been disposed of in the meantime? If so, quit.  
  11.         if (mHelper == null)  
  12.             return;  
  13.   
  14.         // IAB is fully set up. Now, let's get an inventory of stuff  
  15.         // we own.  
  16.         Log.d(TAG, "Setup successful. Querying inventory.");  
  17.         mHelper.queryInventoryAsync(mGotInventoryListener);  
  18.     }  
  19. });  

4.点击购买按钮调用方法,主要是mHelper.launchPurchaseFlow()方法


[java]  view plain  copy
  1. // User clicked the "Buy Gas" button  
  2. public void onBuyGasButtonClicked(View arg0) {  
  3.     Log.d(TAG, "Buy gas button clicked.");  
  4.   
  5.     // launch the gas purchase UI flow.  
  6.     // We will be notified of completion via mPurchaseFinishedListener  
  7.     setWaitScreen(true);  
  8.     Log.d(TAG, "Launching purchase flow for gas.");  
  9.   
  10.     /* 
  11.      * TODO: for security, generate your payload here for verification. See 
  12.      * the comments on verifyDeveloperPayload() for more info. Since this is 
  13.      * a SAMPLE, we just use an empty string, but on a production app you 
  14.      * should carefully generate this. 
  15.      */  
  16.     String payload = "";  
  17.   
  18.     mHelper.launchPurchaseFlow(this, SKU_PACKAGE1, RC_REQUEST, mPurchaseFinishedListener, payload);  
  19. }  

5.verifyDeveloperPayload方法用来在服务器做验证的,起到确认订单的作用,小游戏就免了吧!


[java]  view plain  copy
  1. /** Verifies the developer payload of a purchase. */  
  2.     boolean verifyDeveloperPayload(Purchase p) {  
  3.         String payload = p.getDeveloperPayload();  
  4.   
  5.         /* 
  6.          * TODO: verify that the developer payload of the purchase is correct. 
  7.          * It will be the same one that you sent when initiating the purchase. 
  8.          * 
  9.          * WARNING: Locally generating a random string when starting a purchase 
  10.          * and verifying it here might seem like a good approach, but this will 
  11.          * fail in the case where the user purchases an item on one device and 
  12.          * then uses your app on a different device, because on the other device 
  13.          * you will not have access to the random string you originally 
  14.          * generated. 
  15.          * 
  16.          * So a good developer payload has these characteristics: 
  17.          * 
  18.          * 1. If two different users purchase an item, the payload is different 
  19.          * between them, so that one user's purchase can't be replayed to 
  20.          * another user. 
  21.          * 
  22.          * 2. The payload must be such that you can verify it even when the app 
  23.          * wasn't the one who initiated the purchase flow (so that items 
  24.          * purchased by the user on one device work on other devices owned by 
  25.          * the user). 
  26.          * 
  27.          * Using your own server to store and verify developer payloads across 
  28.          * app installations is recommended. 
  29.          */  
  30.   
  31.         return true;  
  32.     }  

6.下面是执行完购买后的监听方法


[java]  view plain  copy
  1. // Callback for when a purchase is finished  
  2. IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {  
  3.     public void onIabPurchaseFinished(IabResult result, Purchase purchase) {  
  4.         Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);  
  5.         // if we were disposed of in the meantime, quit.  
  6.         if (mHelper == null)  
  7.             return;  
  8.         if (result.isFailure()) {  
  9.             complain("Error purchasing: " + result);  
  10.             setWaitScreen(false);  
  11.             return;  
  12.         }  
  13.         if (!verifyDeveloperPayload(purchase)) {  
  14.             complain("Error purchasing. Authenticity verification failed.");  
  15.             setWaitScreen(false);  
  16.             return;  
  17.         }  
  18.         Log.d(TAG, "Purchase successful.");  
  19.         if (purchase.getSku().equals(SKU_PACKAGE1)) {  
  20.             // bought 1/4 tank of gas. So consume it.  
  21.             Log.d(TAG, "Purchase1 is gas. Starting gas consumption.");  
  22.             mHelper.consumeAsync(purchase, mConsumeFinishedListener);  
  23.         } else if (purchase.getSku().equals(SKU_PACKAGE2)) {  
  24.             // bought the premium upgrade!  
  25.             Log.d(TAG, "Purchase2 is premium upgrade. Congratulating user.");  
  26.             mHelper.consumeAsync(purchase, mConsumeFinishedListener);  
  27.         } else if (purchase.getSku().equals(SKU_PACKAGE3)) {  
  28.             // bought the premium upgrade!  
  29.             Log.d(TAG, "Purchase3 is premium upgrade. Congratulating user.");  
  30.         }  
  31.     }  
  32. };  

7.执行完购买回调后,消耗型商品需要调用消耗方法


IabHelper.OnConsumeFinishedListener mConsumeFinishedListener  = new  IabHelper.OnConsumeFinishedListener()

这句的意思就是消耗掉你刚买的商品,消耗是指在googleplay上的消耗,为什么呢?因为GooglePlay 的In-app-Billing V3.0版本,已经没有管理,非管理的商品,或者像苹果iOS那边消耗性和非消耗性的商品了,在后台新建商品的时候,你会发现全部是受管理的商品,所以在我们购买了消耗型的商品后,在代码中执行mHelper.consumeAsync(purchase,mConsumeFinishedListener);就行了,代表这个商品被消耗了,你还可以购买。下面是消耗后的回调方法:

[java]  view plain  copy
  1. // Called when consumption is complete  
  2.     IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {  
  3.         public void onConsumeFinished(Purchase purchase, IabResult result) {  
  4.             Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);  
  5.   
  6.             // if we were disposed of in the meantime, quit.  
  7.             if (mHelper == null)  
  8.                 return;  
  9.   
  10.             // We know this is the "gas" sku because it's the only one we  
  11.             // consume,  
  12.             // so we don't check which sku was consumed. If you have more than  
  13.             // one  
  14.             // sku, you probably should check...  
  15.             if (result.isSuccess()) {  
  16.                 // successfully consumed, so we apply the effects of the item in  
  17.                 // our  
  18.                 // game world's logic, which in our case means filling the gas  
  19.                 // tank a bit  
  20.                 Log.d(TAG, "Consumption successful. Provisioning.");  
  21.                 //saveData();  
  22.             } else {  
  23.                 complain("Error while consuming: " + result);  
  24.             }  
  25.             updateUi();  
  26.             setWaitScreen(false);  
  27.             Log.d(TAG, "End consumption flow.");  
  28.         }  
  29.     };  

8.最后补充一点,官方例子的方法设计非常合理,一些辅助方法的书写和使用,很经典,值得我们的借鉴。


[java]  view plain  copy
  1. // updates UI to reflect model  
  2.     public void updateUi() {  
  3.           
  4.     }  
  5.   
  6.     // Enables or disables the "please wait" screen.  
  7.     void setWaitScreen(boolean set) {  
  8.         findViewById(R.id.screen_main).setVisibility(set ? View.GONE : View.VISIBLE);  
  9.         findViewById(R.id.screen_wait).setVisibility(set ? View.VISIBLE : View.GONE);  
  10.     }  
  11.   
  12.     void complain(String message) {  
  13.         Log.e(TAG, "**** TrivialDrive Error: " + message);  
  14.         alert("Error: " + message);  
  15.     }  
  16.   
  17.     void alert(String message) {  
  18.         AlertDialog.Builder bld = new AlertDialog.Builder(this);  
  19.         bld.setMessage(message);  
  20.         bld.setNeutralButton("OK"null);  
  21.         Log.d(TAG, "Showing alert dialog: " + message);  
  22.         bld.create().show();  

  1.     }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值