google play以及google pay
接入google play有段时间了,今天抽空留个备份,回忆下心酸的历程
网上已经有很多资料,google爸爸也提供了很多文档。但是对于刚接触的我来说,信息量太大,有点杂乱的感觉。其实整理清楚,那么就非常简单了。这里细节也不详细写了,主要理清楚一些概念。
一、注册google账号,付钱成为开发者人员
二、进入Google Play Console创建你的应用,同时填写一些信息。(APP基本信息,隐私权政策网址等)
三、注意一条信息【让 Google 管理并保护您的应用签名密钥(推荐)!!】谨慎选择!如果同意的话,那么则无法取消了。
这个协议会造成Google针对你提交的签名文件A生成Google保管的另外一个签名文件B,并且B签名文件只会提供给你
MD5、SHA-1、SHA-256一些信息。而没有.jks这样的签名文件!
你的APP提交Google Play后,会剥离你的签名文件,用B签名再给APP打包一次。
这意味着你签名的APP跟从Google Play下载后的APP签名是不一致的!
这会造成一些困扰,比如APP内置版本更新功能、一些SDK无法使用。(如微信SDK是根据签名文件申请的)等等
同时提交还有个坑!安卓一般分发市场,会用到一些第三方加固软件。如果同意该协议,则提交Google Play的APK包不能加固,只能用原始的A签名打包,否则上架后下载安装是白屏的!!!
OK,上面都是一些坑,血泪史啊。悔不当初有没有!但是呢,后续我发现一些优点,也让我非常眼馋。毕竟从同意这个协议开始,就没办法回头了。
优点:
1、google play统计数据。如果是APP内置版本更新功能,是无法统计这个数据的
2、Android App Bundle。这个东西很流弊,很舒坦。google市场根据用户的手机信息,给用户生成合适的apk包。之前不论什么型号的手机,都是下载一个apk包。但是对大屏手机来说,我不需要小屏的资源,32位手机不需要64位资源,OK,删除不需要的。然后发现APK缩小了很多。
这里可能觉得差别不大,因为我打包的时候
安装包缩小了非常多。至于x86 mip是什么,这里暂时不讲解
四、App需要在首页显示隐私权政策网址,需要用户点击是否接受。没有此功能,提交审核会被拒绝
五、是否付费应用。也只有一次选择机会。此处的付费应用代表在gp市场是否免费还是付费下载。应用内付费不在此列
六、如果APP有内置付费内容,则需要先在控制台定义商品
商品ID非常重要。google pay是根据此id来付费结算购买的。ID可以用json存储到app项目中,自己判断,也可以后台给你。
七、google pay(支付)先理清楚概念,再上代码,代码注释非常清楚。谷歌支付跟ios支付流程非常相似
1、订阅 subs,详情百度
2、一次性购买 inapp。根据商品ID下单,如果此商品已被购买且未被消耗,则下单失败、付款成功回调、消耗
接入支付,可以参考以下链接
3、谷歌支付下单时候,额外参数最好是后台给予的订单ID
https://developer.android.com/google/play/billing/billing_integrate.html?hl=zh-cn
https://developer.android.com/google/play/billing/billing_reference.html?hl=zh-cn#getSkuDetails
代码
/*** 测试 google pay* https://developer.android.com/google/play/billing/billing_integrate.html?hl=zh-cn* https://developer.android.com/google/play/billing/billing_reference.html?hl=zh-cn#getSkuDetails* https://developer.android.com/google/play/billing/api#consume*/
class GooglePayActivity : BasicActivity3<ActivityGooglePayBinding>(), View.OnClickListener {var mService: IInAppBillingService? = nullvar mServiceConn: ServiceConnection? = nullvar sub_monthly_price: String? = nullvar querySkus: Bundle? = nullval TAG = "Google pay"companion object {fun startActivity(context: Context) {val intent = Intent(context, GooglePayActivity::class.java)context.startActivity(intent)}}override fun onCreate(savedInstanceState: Bundle?) {//与应用内购买结算服务建立连接mServiceConn = object : ServiceConnection {override fun onServiceDisconnected(name: ComponentName) {mService = nullToastUtils.showLongTip("未链接到google play service")}override fun onServiceConnected(name: ComponentName,service: IBinder) {mService = IInAppBillingService.Stub.asInterface(service)val code = mService!!.isBillingSupported(3, packageName, "inapp")LogUtils.e(TAG, "是否支持pay:$code")if (code != 0) {ToastUtils.showLongTip("暂不支持IBinder版本支付")return}if (mService != null) {initRn()getPurchases()} else {LogUtils.e(TAG, "没走initRn()方法")}}}//onCreate 方法中,通过调用 bindService 方法执行绑定。 向方法传递引用应用内购买结算服务的 Intent 和您创建的一个 ServiceConnection 实例,// 并明确地将 Intent 的目标软件包名称设置为 com.android.vending — Google Play 应用的软件包名称。val serviceIntent = Intent("com.android.vending.billing.InAppBillingService.BIND")serviceIntent.`package` = "com.android.vending"bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE)super.onCreate(savedInstanceState)}override fun getLayoutId(): Int {return R.layout.activity_google_pay}override fun initView() {binding.click = this}override fun setData() {}override fun onClick(v: View?) {when (v?.id) {R.id.titleBreak -> {finish()}R.id.tvPlay1 -> {if (mService != null) {getBuyIntent("10006")} else {ToastUtils.showLongTip("未链接到google play service")}}}}private fun initRn() {LogUtils.e(TAG, "initRn==initRn")// 警告:请不要在主线程上调用 getSkuDetails 方法。 调用此方法会触发网络请求,进而阻塞主线程。 请创建单独的线程并从该线程内部调用 getSkuDetails 方法。Thread(Runnable {//在您的应用中,可以使用 In-app Billing Version 3 API 从 Google Play 查询商品详情。 要将请求传递至应用内购买结算服务,// 首先需要创建一个包含商品 ID 字符串 ArrayList 的 Bundle,该字符串带有键“ITEM_ID_LIST”,每个字符串是可购买商品的商品 ID。var skuList = ArrayList<String>()skuList.add("10006")skuList.add("10128")querySkus = Bundle()querySkus!!.putStringArrayList("ITEM_ID_LIST", skuList)//查询可供购买的商品//要从 Google Play 检索此信息,请在 In-app Billing Version 3 API 上调用 getSkuDetails 方法,// 然后将 In-app Billing API 版本(“3”)、发起调用的应用的软件包名称、商品类型(“应用内”)以及您创建的 Bundle 传递给方法。//应用内商品的类型(“inapp”用于一次性购买,“subs”用于订阅)var skuDetails = mService!!.getSkuDetails(3, packageName, "inapp", querySkus)//查询结果将保存在带有键 DETAILS_LIST 的字符串 ArrayList 中。购买信息存储在 JSON 格式的字符串中//将从之前代码段返回的 skuDetails Bundle 中检索您的应用内商品的价格。val response = skuDetails.getInt("RESPONSE_CODE")LogUtils.e(TAG, "response==$response")if (response == 0) {val responseList = skuDetails.getStringArrayList("DETAILS_LIST")LogUtils.e(TAG, "responseList==" + responseList.toString())for (thisResponse in responseList) {/** 返回值 详情见 https://developer.android.com/google/play/billing/billing_reference.html?hl=zh-cn#getSkuDetails getSkuDetails()方法*/val `object` = JSONObject(thisResponse)val sku = `object`.getString("productId")val price = `object`.getString("price")LogUtils.e(TAG, "price==" + price)if (sku == "sub_monthly")sub_monthly_price = price
// else if (sku == "gas") mGasPrice = price}} else {LogUtils.e(TAG, "response===========" + response)}}).start()}//购买//要从您的应用发起订阅请求,请在应用内购买结算服务上调用 getBuyIntent 方法。 将 In-app Billing API 版本(“3”)、发起调用的应用的软件包名称、要购买商品的商品 ID、// 商品类型(“应用内”或“订阅”)以及 developerPayload 字符串传递给方法。 developerPayload 字符串用于指定您想要 Google Play 随购买信息一同发送的任何其他参数。fun getBuyIntent(productId: String) {try {val buyIntentBundle = mService!!.getBuyIntent(3, packageName,productId, "inapp", "zhtttyyzc")//developerPayload 额外参数 可以设置任意 最好服务器设置 增加安全性 比如后台定义的订单idvar code = buyIntentBundle.getInt("RESPONSE_CODE")if (code == 0) {//如果请求成功,返回的 Bundle 将包含响应代码 BILLING_RESPONSE_RESULT_OK (0) 和您可以用于开始购买流程的 PendingIntent。 要从 Google Play 查看所// 有可能的响应代码,请参阅应用内购买结算参考。 接下来,请使用键 BUY_INTENT 从响应 Bundle 中提取 PendingIntent。val pendingIntent = (buyIntentBundle.getParcelable("BUY_INTENT")) as PendingIntent//要完成购买交易,请调用 startIntentSenderForResult 方法并使用您创建的 PendingIntent。 这里用任意值 1001 用于请求代码。startIntentSenderForResult(pendingIntent.intentSender,1001, Intent(), Integer.valueOf(0), Integer.valueOf(0),Integer.valueOf(0))} else {LogUtils.e(TAG, "发起购买失败code:$code")}} catch (e: Exception) {e.printStackTrace()}}//查询已购买商品(未被消耗)//此方法将返回当前归用户所有但未消费的商品,包括购买的商品和通过兑换促销代码获得的商品//未被消耗 无法再次购买fun getPurchases() {Thread(Runnable {val ownedItems = mService!!.getPurchases(3, packageName, "inapp", null)val response = ownedItems.getInt("RESPONSE_CODE")if (response == 0) {val ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST")val purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST")val signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST")for (dataItem in purchaseDataList) {try {val jo = JSONObject(dataItem)val purchaseToken = jo.getString("purchaseToken")//用于消耗val sku = jo.getString("productId")val developerPayload = jo.getString("developerPayload")consumePurchase(purchaseToken)//立即消耗} catch (e: Exception) {e.printStackTrace()}}}}).start()}//消耗fun consumePurchase(purchaseToken: String) {val response = mService!!.consumePurchase(3, packageName, purchaseToken)LogUtils.e(TAG, "消耗 response$response")if (response == 0) {LogUtils.e(TAG, "消耗 succeed")} else {LogUtils.e(TAG, "消耗 失败")}}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if (requestCode == 1001) {//订单的购买数据是 JSON 格式的字符串,将映射到响应 Intent 中的 INAPP_PURCHASE_DATA 键val responseCode = data?.getIntExtra("RESPONSE_CODE", -1)val purchaseData = data?.getStringExtra("INAPP_PURCHASE_DATA")val dataSignature = data?.getStringExtra("INAPP_DATA_SIGNATURE")if (resultCode == RESULT_OK) {if (responseCode == 0) {try {LogUtils.e(TAG, "支付成功回调结果purchaseData:$purchaseData")val jo = JSONObject(purchaseData)val sku = jo.getString("productId")val purchaseToken = jo.getString("purchaseToken")//用于消耗/*** 开发者指定的字符串,其中包含关于订单的补充信息。当您发出 getBuyIntent 请求时,您可以为此字段指定一个值* 最好是服务器给与的订单ID 进行比对* */val developerPayload = jo.getString("developerPayload")//consumePurchase(purchaseToken)//购买成功 立即消耗} catch (e: JSONException) {LogUtils.e(TAG, "Failed to parse purchase data")e.printStackTrace()}} else {ToastUtils.showLongTip("支付取消")}}}}//安全性建议:在您发送购买请求时,请创建一个可以对此购买请求进行唯一标识的字符串令牌并在 developerPayload 中包含此令牌。您可以将随机生成的字符串作为令牌。 从 Google Play 接收到购买响应时,请确保检查返回的数据签名、orderId 和 developerPayload 字符串。 为了增强安全性,您应在自己安全的服务器上执行检查。 请确保验证 orderId 为您之前未处理的唯一值,且 developerPayload 字符串与您之前通过购买请求发送的令牌相匹配。//重要说明:完成您的 Activity 后,请务必与应用内购买结算服务解除绑定。 如果不解除绑定,开启的服务连接会导致您的设备性能下降。// 此示例说明了如何通过重写 Activity 的 onDestroy 方法对到应用内购买结算的服务连接 mServiceConn 执行解除绑定操作。public override fun onDestroy() {super.onDestroy()if (mService != null) {unbindService(mServiceConn)}}
}
八、Google Play Console渠道
点击对应渠道的管理,如Alpha渠道
可以添加测试人员,输入测试人员的google账号。然后把加入测试的网址发给测试人员,测试人员用google浏览器打开,点击同意加入即可,记得需要先登陆google账号哦。测试人员测试支付,是不需要付费的。
如果测试发现手机调不起google pay?
1、检查手机是否支持谷歌服务
2、检查手机网络是否能科学上网
3、如果APP同意了谷歌签名服务,手机安装的APK包是否跟谷歌市场的签名一致?(这种情况,建议发布个谷歌市场内部测试渠道包,然后从市场下载安装测试)
4、如果排除了已知的可能,那么换个手机试试。手机厂商可能会修改点东西。亲测小米手机某型号怎么都调试不起来,后来换了华为和其他品牌手机,完美调起。
google play以及google pay相关推荐
- 【Google Play】Google Play 开放式测试 ( 简介 | 发布开放式测试版本 )
Google Play 上架完整流程 系列文章目录 [Google Play]创建 Google 开发者账号 ( 注册邮箱账号 | 创建开发者账号 ) [Google Play]创建并设置应用 ( 访 ...
- (转载)Google Analytics(Google分析)使用技巧
Google Analytics(Google分析)是Google的一款免费的网站分析服务,自从其诞生以来,即广受好评.Google Analytics功能非常强大,只要在网站的页面上加入一段代码,就 ...
- Google发布用于Google Cloud的.Net API
Google近期宣布针对Google Cloud API的.Net支持.这包括C#绑定和PowerShell cmdlet.还有一个Visual Studio扩展,它允许在Google Compute ...
- 【转】在你的博客中添加Google地图(Use Google Map API On Your Bolg)
在你的博客中添加Google地图(Use Google Map API On Your Bolg) *+申请一组 Google Maps API Key 在使用 Google Maps API 之前, ...
- Google play billing(Google play 内支付)
http://www.bubuko.com/infodetail-930440.html [html] view plaincopy 如billing开发文档所说,要在你的应用中实现In-app Bi ...
- python google buffer_python调用Google Protocol Buffer
写proto文件 package lm; message Person { required int32 id = 1; required string str = 2; optional int3 ...
- 怎么样用 Google Analytics 区分 Google Shopping 页的流量
我们知道 Google Shopping 收费以来,Google Search 页的 PLA 广告和 Google Shopping 页的流量归在了付费搜索(Medium 是 CPC)流量里面了(收费 ...
- Geek必备神器 - Google眼镜(Google glass)的十大特色
日期:2013-3-1 来源:GBin1.com 虽然目前Google眼镜还处于开发状态,但是相信各位Geek对于这个跨时代的产品肯定是十分有兴趣,小编这里手机了10个Google眼镜的特性,希望能 ...
- Google play billing(Google play 内支付) 上篇
写在前面: 最近Google貌似又被全面封杀了,幸好在此之前,把Google play billing弄完了,现在写篇 博客来做下记录.这篇博客一是自己做个记录,二是帮助其他有需要的人.因为现在基本登 ...
- 怎么使用Google GSC(原google站长工具)?
Google GSC即Google search console(原google站长工具)是谷歌的一种免费的网站管理平台,它的功能强大,使用简单,今天Hunk就来分享下怎么使用谷歌GSC. 温馨提示: ...
最新文章
- 定义一个员工类(JAVA)
- 图像识别工程师 VS The application has requested the Runtime to terminate it in an unusual way.
- 1.6 this关键字详解(3种用法)
- 折叠屏市场价值在哪里?
- 解析《中国互联网软件测试行业2018年度调研报告》
- 秋招注意事项和面试通关攻略
- Linux USB设备驱动程序设计 和 USB下载线驱动设计
- Java多线程学习三十一:ThreadLocal 是用来解决共享资源的多线程访问的问题吗?
- 编程吸金榜:你排第几?网友神回应了 !
- Trained Ternary Quantization
- python爬虫爬取微信_Python爬虫爬取微信小程序
- windows双屏显示如何设置
- postgresql encode函数
- Linux下USB HID device driver研究
- Macbook上Gitlab下载代码
- python写数字,Python3生成手写体数字方法
- ie下载java就花屏,“浏览器花屏的解决方案”的解决方案
- 科技观察:通用人工智能已被中央关注
- 微信小程序开发-页面跳转的几种方式
- node.js爬虫中关村在线电瓶车信息