在写《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. Upgrading PHP on CentOS 6.5 (Final)
  2. java 有穷自动机_Java实现雪花算法(snowflake)
  3. 支付宝问题LaunchServices: ERROR: There is no registered handler for URL scheme alipay
  4. virtual box 安装win8 提示status: 0xc0000225错误的处理
  5. ubuntu查看进程和结束进程
  6. keras 升级_如何入门Keras?
  7. oracle 手动链库,Oracle 数据库干数据库链(Database links)的两个例子
  8. C# 中的 ConfigurationManager类引用方法应用程序配置文件App.config的写法
  9. Centos下安装Scrapy
  10. 【CarMaker学习笔记】与Simulink联合仿真
  11. 华为交换机导入配置_华为交换机配置导入和导出
  12. xcode-instrument
  13. 论物理学与技术革命之间的关系
  14. cf3月活动大全 3月活动汇总2015
  15. 信息收集--关联信息及漏洞情报
  16. laydate 周_第37周动画数据周报 |书灵记1st Kiss火热上线
  17. mysql 取24小时数据_mysql获取24小时前数据
  18. SQL2000重新装,有文件挂起
  19. bootstrap插件summernote 的使用
  20. UIlabel - 富文本属性

热门文章

  1. 机器学习算法实践-树回归-转
  2. Elasticsearch进阶使用-动态模版
  3. 利用PreLoader实现一个平视显示(HUD)效果(可以运用到加载等待效果),并进行简单的讲解
  4. 域名被微信屏蔽拦截的原因和防封方案
  5. 什么是Java虚拟机
  6. 常用的利率定价 - jason的文章
  7. 【愚公系列】2023年06月 网络安全(交通银行杯)-APFS
  8. 关于 atmega128rfa1 并行编程说明
  9. 白嫖立创商城的封装(不丢丝印),亲测有效
  10. 计算机光驱打不开是什么原因,电脑光驱打不开怎么办 电脑光驱打不开解决方法...