在 v4 中,我曾经使用 SkuDetails.price 来获取产品的价格,但现在在 v5 中的新 ProductDetails 中不再可用。
如何获取新版本中产品的价格?
为什么TrivialDrive有两个版本?
https://github.com/googlesamples/android-play-billing
哪个版本应该是学习应用内结算的主要参考项目?版本之间有什么区别?
我的用户SkuType.INAPP已从我的应用程序中购买了items().
在前面推荐的在应用程序内结算的实施中IabHelper.QueryInventoryFinishedListener会返回一个Inventory包含任何项目,他们所拥有.
在新的Play Billing Library中,我使用以下方法:
Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
Run Code Online (Sandbox Code Playgroud)
假设响应代码成功,我查询:
purchasesResult.getPurchasesList()
Run Code Online (Sandbox Code Playgroud)
对于这一小部分用户,列表为空.
作为故障保护,对于上面的否定结果,我继续尝试:
mBillingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP, this);
Run Code Online (Sandbox Code Playgroud)
该 onPurchaseHistoryResponse(final int responseCode, final List<Purchase> purchasesList)
成功详细购买.
对此感到困惑,我要求运行这两个实现的受影响用户确认以下内容:
根据这个帖子的建议,我让他们:
尽管如此,仍然只能queryPurchaseHistoryAsync正确识别他们的帐户拥有的项目.
问题:为什么?
该结算图书馆实现状态:
queryPurchaseHistoryAsync()返回用户为每个SKU进行的最新购买,即使该购买已过期,取消或已消耗.尽可能使用queryPurchases()方法,因为它使用本地缓存,而不是queryPurchaseHistoryAsync()方法.
我已在订单管理中确认购买有效且尚未取消.我不消耗它们,因此它们不能过期.
现在我有一个问题
鉴于对于这些用户我只能以上述方式识别他们的购买,我被迫为所有人实现这种故障保护.
除了因为必须这样做而感到沮丧之外,在您再次阅读之前,这似乎不是太大的问题:
queryPurchaseHistoryAsync()返回用户为每个SKU进行的最新购买,即使该购买已过期,取消或已消耗
因此,在我的标准实施中,我需要检查此购买是否仍然有效.
不幸的是,Purchase对象没有这样的方法来检查其有效性.
所以,我可能需要进行外部检查 …
android in-app-purchase in-app-billing android-billing play-billing-library
我使用的是Google Play结算库2.0.3(implementation 'com.android.billingclient:billing:2.0.3'),它在大多数情况下都可以正常运行,但是对于某些用户,原因未知,querySkuDetailsAsync() method occasionally fails with BillingResponseCode.ERROR (6) error code...
有人知道吗?除了“ API操作期间发生致命错误”之外,其他任何地方都未说明此错误的原因。谁能说出为什么会这样吗?
编辑: 我正在使用文档中的方法(https://developer.android.com/google/play/billing/billing_library_overview):
public interface QuerySkuDetailsListener {
void onSuccess(List<SkuDetails> skuDetailsList);
void onErrorProductsHaveDifferentTypes();
void onBillingClientError(int error_code);
}
public void querySkuDetails(final QuerySkuDetailsListener querySkuDetailsListener, final Product... products) {
if (products.length < 1) {
//ERROR_NO_PRODUCTS_TO_QUERY
throw new NullPointerException();
}
String querySkuType = products[0].getSkuType();
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
List<String> skuList = new ArrayList<>();
for (Product product : products) {
skuList.add(product.getSku());
if (!product.getSkuType().equals(querySkuType)) {
//ERROR_SKU_TYPE_CANT_BE_DIFFERENT
querySkuDetailsListener.onErrorProductsHaveDifferentTypes();
return; …Run Code Online (Sandbox Code Playgroud) android response in-app-billing android-inapp-purchase play-billing-library
我正在尝试创建一个恢复购买系统。我希望,用户可以通过他/她登录的任何设备访问其购买的产品。所以我在应用程序启动时使用“queryPurchaseHistoryAsync()”方法。我的问题从这里开始。
随着 Google 的新实现,与文档相反,queryPurchaseHistoryAsync() 参数发生了变化。现在它将 PurchaseHistoryRecord 对象列表作为参数而不是 Purchase 对象列表。
Android studio 无法解析文档中所述的方法。使用新的 queryPurchaseHistoryAsync() 无论如何我都找不到检查购买状态。(如果它已购买、取消或待处理)。我能够使用“purchase.getPurchaseState()”方法处理 Purchase 对象。
queryPurchaseHistoryAsync() 的文档
billingClient.queryPurchaseHistoryAsync(SkuType.INAPP,
new PurchaseHistoryResponseListener() {
@Override
public void onPurchaseHistoryResponse(BillingResult billingResult,
List<Purchase> purchasesList) {
if (billingResult.getResponseCode() == BillingResponse.OK
&& purchasesList != null) {
for (Purchase purchase : purchasesList) {
// Process the result.
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
我的实现
implementation 'com.android.billingclient:billing:2.0.3'
Run Code Online (Sandbox Code Playgroud)
我的应用程序中的 queryPurchaseHistoryAsync() 方法
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,
new PurchaseHistoryResponseListener() {
@Override
public void onPurchaseHistoryResponse(BillingResult billingResult, List<PurchaseHistoryRecord> purchaseHistoryRecordList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
&& purchaseHistoryRecordList != null) { …Run Code Online (Sandbox Code Playgroud) 我在Android应用中使用Play Billing Library v1.0进行应用内结算支持,并希望允许用户在其有效期内手动续订订阅,以便在适当的时间段内对其进行延期.
当用户可以通过折扣扩展订阅时,它可以用于不同的销售(黑色星期五,新年等).
根据官方文档,这种行为确实可以实现.但我没有找到如何实现它的信息.
我使用以下标准代码购买订阅:
BillingFlowParams.Builder builder = BillingFlowParams.newBuilder()
.setSku(skuId).setType(SkuType.SUBS);
int responseCode = mBillingClient.launchBillingFlow(activity, builder.build());
Run Code Online (Sandbox Code Playgroud)
如果我再次尝试购买相同的订阅,那么
"你已经订阅了XXXXX [确定]"
出现错误消息.
我也尝试使用.addOldSku()构建器方法并在此处传递相同的sku,但它也没有帮助.
重现的步骤(测试帐户):
预计:订阅不再在billingClient列表中.queryPurchases(SUB_SKU_TYPE)返回
实际:订阅仍在列表中的billingClient.queryPurchases(SUB_SKU_TYPE)返回(即使在约1小时后)
报告错误:https://github.com/googlesamples/android-play-billing/issues/122
正如文档中所述,queryPurchases可以在不进行任何网络调用的情况下使用缓存,这可能是导致此问题的原因.queryPurchaseHistoryAsync可能是一个不错的选择,但Purchase类没有实际购买的状态(即SUBSCRIBED,CANCELLED等).
是否有任何选项可以使用Play Billing Lib解决此问题,或者是否需要使用旧的In-App Billing Api进行直接网络呼叫?
我尝试使用 Kotlin 协程为 BillingClient v.2.2.0 编写一个包装器:
package com.cantalk.photopose.billing
import android.app.Activity
import android.content.Context
import com.android.billingclient.api.*
import com.android.billingclient.api.BillingClient.*
import com.cantalk.photopose.util.Logger
import kotlinx.coroutines.CompletableDeferred
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
class BillingClientAsync(context: Context) {
private val billingClient: BillingClient = setupBillingClient(context)
private val pendingPurchaseFlows = HashMap<String, CompletableDeferred<Purchase>>()
private fun setupBillingClient(context: Context): BillingClient {
return newBuilder(context)
.enablePendingPurchases()
.setListener { billingResult, purchases ->
if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
val deferred = pendingPurchaseFlows.remove(purchase.sku)
deferred?.complete(purchase)
}
} else {
val …Run Code Online (Sandbox Code Playgroud) android kotlin android-billing play-billing-library kotlin-coroutines
我现在正在使用新的Play Billing Library
基本上,我按照文档查询要购买的可用项目
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(itemType);
mBillingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(int responseCode,
List<SkuDetails> skuDetailsList) {
listener.onSkuDetailsResponse(responseCode, skuDetailsList);
}
Run Code Online (Sandbox Code Playgroud)
但是,responseCode为0,列表也为空.但我检查了BillingSetupFinished是否成功.提供给SkuDetailsParams.Builder的skuList不为空,skuList(sku_id)中的值也与Google Play控制台上指定的产品ID相同.
有谁知道原因?谢谢!!
android android-billing android-inapp-purchase play-billing-library
我已使用应用内结算库在应用中添加订阅。一切正常,但是我找不到如何获得用户当前有效的订阅?
根据docs,该方法queryPurchaseHistoryAsync将返回用户针对每个SKU进行的最新购买,即使该购买已过期,取消或消费了。因此,我不知道当前的订阅是否处于活动状态。
根据此帖子,如果我们取消订阅,则该订阅仍将被视为当天有效。但是我得到的响应中的订阅已在15天之前被取消。
任何帮助将不胜感激。提前致谢。
android in-app-billing google-play in-app-subscription play-billing-library