在写《google应用内支付 in-app billing(二)》的时候我并没有写这篇文章的前传《google应用内支付 in-app billing(一)》,留到后面再写吧.......下面进入正题。

一、in-app billing 的完整接入流程如下:

1、添加 in-app billing library;

2、完善AndroidManifest.xml,添加所需权限等;

3、创建ServiceConnection,并绑定到IInAppBillingService;

4、从我们的APP发送支付request请求到IInAppBillingService;

5、从google play 获得response

二、把AIDL文件导入到项目中,为项目和google play通信做准备

获得AIDL文件的方法:

1、打开android SDK manager

2、选中extras,并选中google play billing library

3、最后点击install package按钮

4、在自己项目的src下建立包名为com.android.vending.billing的包,并把刚才下载好的IInAppBillingService.aidl文件考入改包下(IInAppBillingService.aidl在sdk/extras/google/play_billing下)

5、build一下你的project,你会发现在/gen下有一个名为IInAppBillingService.java的文件,接下来你就可以在项目中调用它

三、完善AndroidManifest.xml文件

in-app billing是依赖于google play的,google play相当于一个我们项目与google play server的通信中介。而要使用google play就必须要声明如下权限:

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

四、创建ServiceConnection,并绑定到IInAppBillingService

为了实现自己的app和google play进行通信,必须实现一个ServiceConnection。主要步骤如下:

1、把自己的项目bind到IInAppBillingService;

2、以IPC的方式发送支付request;

3、处理google play返回的response

(一)把自己的项目bind到IInAppBillingService

(1)创建ServiceConnection,并获得IInAppBillingService示例

在Activity中示例化一个ServerConnection,并实现它的两个方法onServiceConnected()和onServiceDisconnectrd(),并在onServiceConnection()方法里获得IInAppBillingService。

private IInAppServiceConnection mService;

private ServiceConnection mServiceConn = new ServiceConnection(){

@Override

public void onServiceConnected(ComponentName name, IBinder service){

//获得IInAppBillingService

mService = IInAppServiceConnection.Stub.asInterface(service);

}

@Override

public void onServiceDisconnected(ComponentName name){

mService = null;

}

}

(2)在Activity的onCreate()中bindService。根据官网的解释,在bind时候要在Intent中明确要启动google play Service(即setPackage("com.android.vending")),这样能够避免request被恶意截取。详情如下:

@Override

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Intent serviceIntent = new Intent("com.android.vending.billing.IInAppBillingService.BIND");

serviceIntent.setPackage("com.android.vending");

bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);

}

接下来你就可以使用mService与google play Service进行通信了。

注意:在退出程序的时候一定要记得unbindService,要不然会使你的设备性能降低。

@Override

public void onDestroy(){

super.onDestroy();

if(mService != null){

unbindService(mServiceConn);

}

}

五、发送支付请求

在in-app billing中,我们的app不必直接去管理每一个订单,当某一个物品被用户所购买,google play会自动识别该物品被某一用户做拥有,并阻止他重复购买该物品,除非他已经消费完了。你能做的就是在你的app中控制每一个物品的消费方式,然后通知google play,告诉它该物品是否可以再次购买。你还可以再app里向google play查询该用户都购买了什么产品 。

(一)查询商品详情(注意:此为网络请求,因此不要放在主线程中)

主要做法是创建一个Bundle对象,然后Bundle里携带一个装载有商品ids的ArrayList,最后调用mService.getSkuDetails()来查询商品详情。具体如下:

ArrayList<String> skuList = new ArrayList<String>();

skuList.add("premiumUpgrade");

skuList.add("gas");

Bundle querySkus = new Bundle();

querySkus.putStringArrayList("ITEM_ID_LIST", skuList);

接着再调用:

Bundle skuDetails = mService.getSkuDetails(3, getPackageName(), "inapp", qureySkus);//第一个参数3是指API版本号,"inapp"是指支付方式。

(二)获取商品详情

如果请求成功,则返回的id是BILLING_RESPONSE_RESULT_OK(即0),返回的商品详情是以JSON的形式放在一个ArrayList中,改ArrayList的key是DETAIL_LIST。以下是解析的代码:

int response = skuDetails.getInt("RESPONSE_CODE");

if(response == 0){

ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");

for(String thisResponse : responseList){

JSONObject object = new JSONObject(thisResponse);

String sku = object.getString("productId");

String price = object.getString("price");

if(sku.equals("premiumUpgrade")){

mPemiumUpgradePrice = price;

}else if(sku.equals("gas")){

mGasPrice = price;

}

}

}

(三)购买商品

(1)发送购买请求

Bundle buyIntentBundle = mService.getBuyIntentBundle(3, getPackageName(), sku, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");

参数解释:3为API版本号;sku为产品id;inapp是支付方式;最后一个参数是developerpayload(我理解的是这个参数也是随机凑合的一个参数,用于验证和对比以确认购买商品的请求是否是自己发送,因为后面购买成功后也会返回一个developerpayload,google官网是这样解释的The developerPayload String is used to specify any additional arguments that you want Google Play to send back along with the purchase information.)

(2)解析请求结果

购买请求发送后google play会返回一个Bundle结果(即上面的buyIntentBundle),如果请求成功则返回BILLING_RESPONSE_RESULT_OK(0),还有一个PendingIntent(key为BUY_INTENT),获取PendingIntent的方法如下:

PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");

startIntentSenderForResult(pendingIntent.getIntentSender(), 1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

参数解释:1001是一个随机的request code;

接着实现Activity中的onActivityResult()方法来接收google play返回的结果:

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data){

if(requestCode == 1001){//上面的随机requestCode在此用到了

int responseCode = data.getIntExtra("RESPONSE_CODE", 0);

String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");

String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");

if(resultCode == RESULT_OK){

try{

JSONObject jo = new JSONObject(purchaseData);

String sku = jo.getString("productId");

}catch(JSONException e){

e.printStackTrace();

}

}

}

}

返回结果如下所示:

'{"orderId":"12999763169054705758.1371079406387615","packageName":"com.example.app","productId":"exampleSku","purchaseTime":1345678900000,"purchaseState":0,"developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ","purchaseToken":"opaque-token-up-to-1000-characters"}'

注意:1、google play返回的purchaseToken会在其他方法中用到(比如消费产品的时候),所以要保存起来。

2、google上有这么一段安全方面的提示,但我不是很了解,所以摘抄如下:

Security Recommendation: When you send a purchase request, create a String token that uniquely identifies this purchase request and include this token in the developerPayload.You can use a randomly generated string as the token. When you receive the purchase response from Google Play, make sure to check the returned data signature, the orderId, and the developerPayload String. For added security, you should perform the checking on your own secure server. Make sure to verify that the orderId is a unique value that you have not previously processed, and the developerPayload String matches the token that you sent previously with the purchase request.

六、查询已购产品

根据google官网的说法,正常情况下,每一次查询最多只能查询出700个已购产品,如果要查更多则需要另外做一些处理,此处不再给出......下面是查询例子:

Bundle ownedItems = mService.getPurchase(3, getPackageName, "inapp", null);

int response = ownedItems.getInt("RESPONSE_CODE");

if(response == 0){

ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");

ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");

ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");

ArrayList<String> continuationToken = ownedItems.getStringArrayList("INAPP_CONTINUATION_TOKEN");

for(int i=0; i<purchaseDataList.size; i++){

String sku = ownedSkus.get(i);

String purchaseData = purchaseDataList.get(i);

String signature = signatureList.get(i);

}

}

七、消费已购产品

int response = mService.consumePurchase(3, getPackageName(), token);

注意:1、该请求属于网络请求,不要放在主线程之中;

2、在你进行消费之前,你必须执行消费请求,确保返回的是有效商品

八、订阅式购买

注意:订阅式购买与其它方式不同的是其购买方式是“subs”而不是“inapp”

(一)购买

Bundle bundle = mService.getBuyIntent(3, getPackageName(), sku, "subs", developerPayload);

PendingIntent pendingIntent = bundle.getParcelable("RESPONSE_BUY_INTENT");

if(bundle.getInt("RESPONSE_CODE") == BILLING_RESPONSE_RESULT_OK){

//该方法会唤醒google play的支付Dialog

startIntentSenderForResult(pendingIntent.getIntentSender(), 1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

}

(二)查询已订阅

Bundle activeSubs = mService.getPurchase(3, getPackageName(), "subs", token);

(九)结束语

这是第一篇真正意义上的博文,内容都是翻译至Android开发文档的,为自己的小进步贺喜一下,也希望有不足的地方大家帮忙提出改进!谢谢!!

google应用内支付 in-app billing(二)相关推荐

  1. SDK接入(2)之Android Google Play内支付(in-app Billing)接入

    SDK接入(2)之Android Google Play内支付(in-app Billing)接入 SDK接入(2)之Android Google Play内支付(in-app Billing)接入 ...

  2. 集成Google应用内 支付 或者 订阅

    要集成Google应用内支付 先要了解文档 集成文档: https://developer.android.google.cn/google/play/billing/integrate 1.创建Go ...

  3. Google play billing(Google play 内支付)

    http://www.bubuko.com/infodetail-930440.html [html] view plaincopy 如billing开发文档所说,要在你的应用中实现In-app Bi ...

  4. Google play billing(Google play 内支付) 下篇

    开篇: 如billing开发文档所说,要在你的应用中实现In-app Billing只需要完成以下几步就可以了. 第一,把你上篇下载的AIDL文件添加到你的工程里,第二,把<uses-permi ...

  5. Google play billing(Google play 内支付) 上篇

    写在前面: 最近Google貌似又被全面封杀了,幸好在此之前,把Google play billing弄完了,现在写篇 博客来做下记录.这篇博客一是自己做个记录,二是帮助其他有需要的人.因为现在基本登 ...

  6. SDK接入(之Android Google Play内支付(in-app Billing)接入的细节

    翻了很多文档,大致流程 懂了,实际上就能上手了,长篇大论是很好,但是关键要素也是决定效率的因素,有些小问题,决定是否成功与否. 首先 下载sdk,在github.com 的google sample里 ...

  7. Google in app billing 应用内支付

    一 简介 Google in app billing 是google play 商店的应用内支付,他是一种应用内的虚拟的道具支付服务,支持应用内支付(inapp)和订阅(subs)两种模式; 在中国, ...

  8. Google支付(In-app Billing)接入

    该文档基于第3版. 应用内结算简介 一.概述 使用应用内结算(In-app Billing)时,我们的应用通过相应的API来访问In-app Billing服务.应用不直接与Google Play服务 ...

  9. 安卓集成google内支付

    Google Play Console创建应用 我的应用是后台人员完成的,具体的可以参考Google Play Console创建应用其中需要注意的是添加测试人员只是测试APK包,需要进行内支付测试则 ...

最新文章

  1. Linux设置root默认密码
  2. oracle系统user$,Oracle 系统变量函数介绍
  3. dateutil 日期计算_日期时间 - 日期时间工具-DateUtil - 《Hutool 参考文档》 - 书栈网 · BookStack...
  4. PAT:1032. Sharing (25) AC
  5. 1000道Python题库系列分享九(31道)
  6. python粘性拓展_Python拓展
  7. 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_18maven的java工程取mysql数据库...
  8. Java设计文本编辑器
  9. mysql注入转义绕过_SQL注入防御绕过——二次注入
  10. php ftps,使用PHP Curl的FTPS获得部分下载
  11. 家庭版茄汁味锅包肉的做法
  12. php语法变化大,浅析PHP7新功能及语法变化总结
  13. GitHub学生优惠:repl.it 使用--Python爬虫示例
  14. Java简易转码工具(一个字符串编码是GBK的文本文件,内容转成UTF-8编码)
  15. vue2 项目启动一直卡在98%Starting development server...98% after emitting CopyPlugin
  16. 【REVERSE】REVERSE入门
  17. 工程力学(13)—扭转二:等值圆轴横截面上的应力
  18. 小技巧 打印出emoji表情
  19. mac 防止 下载 睡眠_如何暂时防止Mac进入睡眠状态
  20. Conflux伍鸣:用DAG结构提升中本聪共识的吞吐率

热门文章

  1. 书法教学软件适合哪些老师使用
  2. 运维人员的得力助手——HotDB 智能巡检
  3. 计算机图形学画点函数
  4. 全栈工程师到底有什么用
  5. 有机棉与彩色棉的比较
  6. 清华经管联手百度:中国AI社会认知与应用需求研究报告
  7. Springboot+mysql学生就业信息管理系统-计算机毕业设计源码95340
  8. android 弹球碰撞
  9. ?Winxp + Vista + Mac OSX + Ubuntu
  10. VS2015调试时 string 值为nops = xxxxxxxxxxxx 的一个解决办法