Android开发文档
支付
货币本地化

1. 功能概述

1.1 需求介绍

货币本地化是指根据目标访问者Google Play账户所在地区来动态调整App内货币符号和本地货币商品价格,以更符合该国家和地区的用户使用习惯。

1.2 目标步骤

  1. 从Google Play通过SDK获取到配置好的商品数据
  2. 处理商品价格
  3. 价格显示

2. 准备条件

  • Google Play后台配置完商品
  • 后台管理系统配置完商品
  • Google Play结算库等前置工作接入完成

3. 功能实现

本文采用结算库版本6来开发

3.1 查询商品详情数据

首先创建BillingClient客户端,并通过startConnection()与Google Play建立连接,完了之后,我们可以通过queryProductDetailsAsync()方法查询商品详情,

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()
 
billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

在上面返回的结果中,我们可以通过调用ProductDetails对象的各种方法来查看应用内的商品相关信息,比如其价格或者说明,上面代码中返回的ProductDetailsList列表,我们取出某一个ProductDetails:

val productDetails = productDetailsList[0]
// 对于一次性购买商品
val purchaseOfferDetails = productDetails.oneTimePurchaseOfferDetails
val formattedPrice = purchaseOfferDetails.formattedPrice  //  $4.99
val priceAmountMicros = purchaseOfferDetails.priceAmountMicros  // 49912392
val priceCurrencyCode = purchaseOfferDetails.priceCurrencyCode  // 货币代码 USD
// 对于订阅型商品
val purchaseOfferDetails = productDetails.subscriptionOfferDetails?.get(0)?.pricingPhases?.pricingPhaseList?.get(0)
val formattedPrice = purchaseOfferDetails.formattedPrice  //  $4.99
val priceAmountMicros = purchaseOfferDetails.priceAmountMicros  // 49912392
val priceCurrencyCode = purchaseOfferDetails.priceCurrencyCode  // 货币代码 USD

3.2 处理商品价格

我们可以通过上面代码获取到商品格式化后的价格formattedPrice,已经经过汇率换算,直接显示即可,对于部分需要计算的金额,可以使用priceAmountMicros,然后除以1000000,保留两位小数,即可取得原始金额数据,然后再进行计算,比如显示 "$4.99/Mon"

// 获取货币符号 $
val currencySymbol = Currency.getInstance(purchaseOfferDetails.priceCurrencyCode).getSymbol(Locale.getDefault())
// 获取单月价格
val price = purchaseOfferDetails.priceAmountMicros.div(1000000).div(12)
// 最后拼接显示
val priceTxt = "$currencySymbol $price/Mon"

3.3 价格显示

最后可以通过数据绑定或者命令式编程等方式赋值来显示数据

4. 常见问题

  1. 问题1:金额显示不正确
  • 原因:对priceAmountMicros理解不正确,用在单位时表示百万分之一
  • 解决方案:应当除以1000000
  1. 问题2:货币符号显示不正确
  • 原因:getSymbol方法如果不传Locale对象的话,默认是英语en
  • 解决方案:要传所在地区,这里一般指手机所选择的Locale国家,可以通过Locale.getDefault()方法获取

5. 参考引用