在我的应用中,我有订阅。我使用IInAppBillingService以经典方式实现了购买流程并检查订阅状态。我用这种方式遇到了一些问题。大约1%的用户抱怨说,在成功购买订阅后,这些订阅在应用程序中无效。我问Google Pla对这个问题的支持。他们建议使用新的播放结算库。我查看了说明https://codelabs.developers.google.com/codelabs/play-billing-codelab/#6中的示例。但是,此示例不考虑检查订阅的状态。
我还在页面https://developer.android.com/google/play/billing/billing_library.html上找到了以下内容:" Google Play服务会返回登录到设备的用户帐户所做的购买。如果请求成功,则播放计费库将查询结果存储在“购买对象列表”中。要检索列表,请调用PurchasesResult对象上的getPurchasesList()方法。"
所以从教程中的BillingManager类我添加了一个代码来检查订阅的购买:
public Purchase.PurchasesResult querySubscriptionPurchases() {
return mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
}
在MainActivity中使用BillingManager:
mBillingManager = new BillingManager(this);
Purchase.PurchasesResult purchasesResult = mBillingManager.querySubscriptionPurchases();
if (purchasesResult != null) {
List<Purchase> p = purchasesResult.getPurchasesList();
}
当我运行app时,在logcat中我看到&#34; I / BillingManager:onBillingSetupFinished()响应:0&#34;。连接成功了吗?
但purchaseResult为空,我无法获取购买列表以探索此列表包含的内容以获取有效订阅的SKU。在调试模式下,使用IInAppBillingService的经典方式成功返回购买,我有一个有效的订阅测试,它可以工作。
BillingManager的完整列表:
public class BillingManager implements PurchasesUpdatedListener {
private static final String TAG = "BillingManager";
private final BillingClient mBillingClient;
private final Activity mActivity;
private static final HashMap<String, List<String>> SKUS;
static
{
SKUS = new HashMap<>();
SKUS.put(BillingClient.SkuType.SUBS, Arrays.asList("no_ads", "sub2", "sub3"));
}
public BillingManager(Activity activity) {
mActivity = activity;
mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
mBillingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponse) {
if (billingResponse == BillingClient.BillingResponse.OK) {
Log.i(TAG, "onBillingSetupFinished() response: " + billingResponse);
} else {
Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
}
}
@Override
public void onBillingServiceDisconnected() {
Log.w(TAG, "onBillingServiceDisconnected()");
}
});
}
@Override
public void onPurchasesUpdated(@BillingClient.BillingResponse int responseCode,
List<Purchase> purchases) {
Log.d(TAG, "onPurchasesUpdated() response: " + responseCode);
}
public List<String> getSkus(@BillingClient.SkuType String type) {
return SKUS.get(type);
}
private void startServiceConnectionIfNeeded(final Runnable executeOnSuccess) {
if (mBillingClient.isReady()) {
if (executeOnSuccess != null) {
executeOnSuccess.run();
}
} else {
mBillingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponse) {
if (billingResponse == BillingClient.BillingResponse.OK) {
Log.i(TAG, "onBillingSetupFinished() response: " + billingResponse);
if (executeOnSuccess != null) {
executeOnSuccess.run();
}
} else {
Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
}
}
@Override
public void onBillingServiceDisconnected() {
Log.w(TAG, "onBillingServiceDisconnected()");
}
});
}
}
public Purchase.PurchasesResult querySubscriptionPurchases() {
return mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
}
public void querySkuDetailsAsync(@BillingClient.SkuType final String itemType,
final List<String> skuList, final SkuDetailsResponseListener listener) {
// Specify a runnable to start when connection to Billing client is established
Runnable executeOnConnectedService = new Runnable() {
@Override
public void run() {
SkuDetailsParams skuDetailsParams = SkuDetailsParams.newBuilder()
.setSkusList(skuList).setType(itemType).build();
mBillingClient.querySkuDetailsAsync(skuDetailsParams,
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(int responseCode,
List<SkuDetails> skuDetailsList) {
listener.onSkuDetailsResponse(responseCode, skuDetailsList);
}
});
}
};
// If Billing client was disconnected, we retry 1 time and if success, execute the query
startServiceConnectionIfNeeded(executeOnConnectedService);
}
public void startPurchaseFlow(final String skuId, final String billingType) {
// Specify a runnable to start when connection to Billing client is established
Runnable executeOnConnectedService = new Runnable() {
@Override
public void run() {
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setType(billingType)
.setSku(skuId)
.build();
mBillingClient.launchBillingFlow(mActivity, billingFlowParams);
}
};
// If Billing client was disconnected, we retry 1 time and if success, execute the query
startServiceConnectionIfNeeded(executeOnConnectedService);
}
public void destroy() {
mBillingClient.endConnection();
}
}
答案 0 :(得分:1)
我使用了TrivialDrive示例中的代码。现在它有效。
MainActivity中的:
mUpdateListener = new myBillingUpdateListener();
mBillingManager = new BillingManager(this, getUpdateListener());
和
@Override
public void onPurchasesUpdated(List<Purchase> purchaseList) {
for (Purchase purchase : purchaseList) {
switch (purchase.getSku()) {
case "no_ad":
doNotShowAds = true;
break;
}
}
}
在BillingManager中:
@Override
public void onPurchasesUpdated(int resultCode, List<Purchase> purchases) {
if (resultCode == BillingClient.BillingResponse.OK) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
mBillingUpdatesListener.onPurchasesUpdated(mPurchases);
} else if (resultCode == BillingClient.BillingResponse.USER_CANCELED) {
Log.i(TAG, "onPurchasesUpdated() - user cancelled the purchase flow - skipping");
} else {
Log.w(TAG, "onPurchasesUpdated() got unknown resultCode: " + resultCode);
}
}