google应用内支付 in-app billing(二)
在写《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, theorderId
, and thedeveloperPayload
String. For added security, you should perform the checking on your own secure server. Make sure to verify that theorderId
is a unique value that you have not previously processed, and thedeveloperPayload
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(二)相关推荐
- SDK接入(2)之Android Google Play内支付(in-app Billing)接入
SDK接入(2)之Android Google Play内支付(in-app Billing)接入 SDK接入(2)之Android Google Play内支付(in-app Billing)接入 ...
- 集成Google应用内 支付 或者 订阅
要集成Google应用内支付 先要了解文档 集成文档: https://developer.android.google.cn/google/play/billing/integrate 1.创建Go ...
- Google play billing(Google play 内支付)
http://www.bubuko.com/infodetail-930440.html [html] view plaincopy 如billing开发文档所说,要在你的应用中实现In-app Bi ...
- Google play billing(Google play 内支付) 下篇
开篇: 如billing开发文档所说,要在你的应用中实现In-app Billing只需要完成以下几步就可以了. 第一,把你上篇下载的AIDL文件添加到你的工程里,第二,把<uses-permi ...
- Google play billing(Google play 内支付) 上篇
写在前面: 最近Google貌似又被全面封杀了,幸好在此之前,把Google play billing弄完了,现在写篇 博客来做下记录.这篇博客一是自己做个记录,二是帮助其他有需要的人.因为现在基本登 ...
- SDK接入(之Android Google Play内支付(in-app Billing)接入的细节
翻了很多文档,大致流程 懂了,实际上就能上手了,长篇大论是很好,但是关键要素也是决定效率的因素,有些小问题,决定是否成功与否. 首先 下载sdk,在github.com 的google sample里 ...
- Google in app billing 应用内支付
一 简介 Google in app billing 是google play 商店的应用内支付,他是一种应用内的虚拟的道具支付服务,支持应用内支付(inapp)和订阅(subs)两种模式; 在中国, ...
- Google支付(In-app Billing)接入
该文档基于第3版. 应用内结算简介 一.概述 使用应用内结算(In-app Billing)时,我们的应用通过相应的API来访问In-app Billing服务.应用不直接与Google Play服务 ...
- 安卓集成google内支付
Google Play Console创建应用 我的应用是后台人员完成的,具体的可以参考Google Play Console创建应用其中需要注意的是添加测试人员只是测试APK包,需要进行内支付测试则 ...
最新文章
- Linux设置root默认密码
- oracle系统user$,Oracle 系统变量函数介绍
- dateutil 日期计算_日期时间 - 日期时间工具-DateUtil - 《Hutool 参考文档》 - 书栈网 · BookStack...
- PAT:1032. Sharing (25) AC
- 1000道Python题库系列分享九(31道)
- python粘性拓展_Python拓展
- 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_18maven的java工程取mysql数据库...
- Java设计文本编辑器
- mysql注入转义绕过_SQL注入防御绕过——二次注入
- php ftps,使用PHP Curl的FTPS获得部分下载
- 家庭版茄汁味锅包肉的做法
- php语法变化大,浅析PHP7新功能及语法变化总结
- GitHub学生优惠:repl.it 使用--Python爬虫示例
- Java简易转码工具(一个字符串编码是GBK的文本文件,内容转成UTF-8编码)
- vue2 项目启动一直卡在98%Starting development server...98% after emitting CopyPlugin
- 【REVERSE】REVERSE入门
- 工程力学(13)—扭转二:等值圆轴横截面上的应力
- 小技巧 打印出emoji表情
- mac 防止 下载 睡眠_如何暂时防止Mac进入睡眠状态
- Conflux伍鸣:用DAG结构提升中本聪共识的吞吐率