Android 如何在新的Google应用内购买中处理具有购买历史记录的购买状态
我正在尝试创建一个恢复购买系统。我想,用户可以访问其购买的产品,无论他/她登录哪个设备。所以我在应用程序启动时使用“queryPurchaseHistoryAsync()”方法。我的问题从这里开始 与文档相反,Google的新实现改变了queryPurchaseHistoryAsync()参数。现在它将PurchaseHistoryRecord对象列表作为参数,而不是PurchaseHistoryRecord对象列表 Android studio无法解析文档中所述的方法。使用新的queryPurchaseHistoryAsync()时,我找不到任何检查购买状态的方法。(如果是已购买、已取消或挂起)。我可以通过“Purchase.getPurchaseState()”方法处理Purchase对象 queryPurchaseHistoryAsync()的文档 我的应用程序中的queryPurchaseHistoryAsync()方法Android 如何在新的Google应用内购买中处理具有购买历史记录的购买状态,android,in-app-purchase,in-app-billing,play-billing-library,Android,In App Purchase,In App Billing,Play Billing Library,我正在尝试创建一个恢复购买系统。我想,用户可以访问其购买的产品,无论他/她登录哪个设备。所以我在应用程序启动时使用“queryPurchaseHistoryAsync()”方法。我的问题从这里开始 与文档相反,Google的新实现改变了queryPurchaseHistoryAsync()参数。现在它将PurchaseHistoryRecord对象列表作为参数,而不是PurchaseHistoryRecord对象列表 Android studio无法解析文档中所述的方法。使用新的queryPur
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,
new PurchaseHistoryResponseListener() {
@Override
public void onPurchaseHistoryResponse(BillingResult billingResult, List<PurchaseHistoryRecord> purchaseHistoryRecordList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
&& purchaseHistoryRecordList != null) {
for (PurchaseHistoryRecord purchaseHistoryRecord : purchaseHistoryRecordList) {
HandleOldGetting(purchaseHistoryRecord.getSku());
}
}
}
billingClient.queryPurchaseHistoryAsync(billingClient.SkuType.INAPP,
新的PurchaseHistoryResponseListener(){
@凌驾
PurchaseHistoryResponse(BillingResult BillingResult,List purchaseHistoryRecordList)上的公共无效{
如果(billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK
&&purchaseHistoryRecordList!=空){
用于(PurchaseHistoryRecord PurchaseHistoryRecord:purchaseHistoryRecordList){
HandleOldGetting(purchaseHistoryRecord.getSku());
}
}
}
谷歌发布说明(2019年5月):
为了尽量减少混淆,queryPurchaseHistoryAsync()现在返回
PurchaseHistoryRecord对象而不是Purchase对象。PurchaseHistoryRecord对象与Purchase对象相同,只是它只反映QueryPurchaseHistorySync()返回的值并且不包含autoRenewing、orderId和packageName字段。请注意,返回的数据没有任何更改-queryPurchaseHistoryAsync()返回与以前相同的数据。“
但发行说明和文档都没有说明如何使用PurchaseHistoryRecord检查购买状态
感谢您阅读本文,非常感谢您的帮助。到目前为止,我一直在使用queryPurchases()自动恢复购买,因为它不需要任何网络连接 Google play应用程序与帐户相关的缓存正在为所有设备更新。在许多情况下,您不需要调用queryPurchaseHistoryAsync进行恢复 正如@bospehre comment中所述。它有一个缺点,因为它依赖于缓存。所以我们仍然需要检查购买情况,并通过网络调用恢复它们 对于queryPurchaseHistory异步调用,我们可以获取购买sku和令牌。如果您按照Google的建议使用服务器保存订阅数据。您可以通过服务器检查此订阅的情况 以下是还原用户的最新订阅的示例
billingManager.billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS) { billingResult, purchaseHistoryRecords ->
if (purchaseHistoryRecords != null) {
var activePurchaseRecord : PurchaseHistoryRecord? = null
if (purchaseHistoryRecords.size > 0) {
// Get the latest subscription. It may differ for developer needs.
for (purchaseHistoryRecord in purchaseHistoryRecords) {
Log.d(billingLogs, "Purchase History Record : $purchaseHistoryRecord")
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
if (subSkuListHelper.getSkuList().contains(purchaseHistoryRecord.sku)
) {
if (activePurchaseRecord == null) {
activePurchaseRecord = purchaseHistoryRecord
} else {
if (purchaseHistoryRecord.purchaseTime > activePurchaseRecord.purchaseTime) {
activePurchaseRecord = purchaseHistoryRecord
}
}
}
}
}
Toast.makeText(
this,
"Subscription Purchases found, Checking validity...",
Toast.LENGTH_SHORT
).show()
// Make a network call with sku and purchaseToken to get subscription info
//Subscription Data Fetch is a class that handling the networking
activePurchaseRecord?.let { SubscriptionDataFetch(
this,
billingManager.billingClient
)
.executeNetWorkCall(
getString(R.string.ubscription_check_endpoint),
it.sku,
it.purchaseToken
)
}
}
else {
Log.d(billingLogs, "Purchase History Record not found size 0") }
}
else {
Toast.makeText(
this,
"Purchase not found",
Toast.LENGTH_SHORT
).show()
Log.d(billingLogs, "Purchase History Record not found null")
}
}
使用“queryPurchases()”它有一个固有的缺点,即它不是实时的。在其他设备上进行的购买可能需要几天才能显示出来,然后才能进行适当的同步,甚至更长时间。因此,我被用户的抱怨淹没了。这个答案是非常错误的,建议进行queryPurchase是的,如果您的internet连接处于活动状态,我将此设置为:ConnectionManagercm=(ConnectionManager)context.getSystemService(context.CONNECTIVITY_SERVICE);NetworkInfo-activeNetwork=cm.getActiveNetworkInfo();
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,
new PurchaseHistoryResponseListener() {
@Override
public void onPurchaseHistoryResponse(BillingResult billingResult, List<PurchaseHistoryRecord> purchaseHistoryRecordList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
&& purchaseHistoryRecordList != null) {
for (PurchaseHistoryRecord purchaseHistoryRecord : purchaseHistoryRecordList) {
HandleOldGetting(purchaseHistoryRecord.getSku());
}
}
}
billingManager.billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS) { billingResult, purchaseHistoryRecords ->
if (purchaseHistoryRecords != null) {
var activePurchaseRecord : PurchaseHistoryRecord? = null
if (purchaseHistoryRecords.size > 0) {
// Get the latest subscription. It may differ for developer needs.
for (purchaseHistoryRecord in purchaseHistoryRecords) {
Log.d(billingLogs, "Purchase History Record : $purchaseHistoryRecord")
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
if (subSkuListHelper.getSkuList().contains(purchaseHistoryRecord.sku)
) {
if (activePurchaseRecord == null) {
activePurchaseRecord = purchaseHistoryRecord
} else {
if (purchaseHistoryRecord.purchaseTime > activePurchaseRecord.purchaseTime) {
activePurchaseRecord = purchaseHistoryRecord
}
}
}
}
}
Toast.makeText(
this,
"Subscription Purchases found, Checking validity...",
Toast.LENGTH_SHORT
).show()
// Make a network call with sku and purchaseToken to get subscription info
//Subscription Data Fetch is a class that handling the networking
activePurchaseRecord?.let { SubscriptionDataFetch(
this,
billingManager.billingClient
)
.executeNetWorkCall(
getString(R.string.ubscription_check_endpoint),
it.sku,
it.purchaseToken
)
}
}
else {
Log.d(billingLogs, "Purchase History Record not found size 0") }
}
else {
Toast.makeText(
this,
"Purchase not found",
Toast.LENGTH_SHORT
).show()
Log.d(billingLogs, "Purchase History Record not found null")
}
}