I refresh to android billing version 4 and 2 things are not working anymore.
First I have this:
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
Purchase.PurchasesResult queryAlreadyPurchasesResult = billingClient.queryPurchases(INAPP); // deprecated
List<Purchase> alreadyPurchases = queryAlreadyPurchasesResult.getPurchasesList();
if(alreadyPurchases!=null){
handlePurchases(alreadyPurchases);
}
}
queryPurchases is deprecated.
Second I have this:
void handlePurchases(List<Purchase> purchases) {
for(Purchase purchase:purchases) {
//if item is purchased
if (PRODUCT_ID.equals(purchase.getSku()) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED)
{
if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
// Invalid purchase
// show error to user
Toast.makeText(getApplicationContext(), R.string.plus_error, Toast.LENGTH_SHORT).show();
return;
}
getSku() was working, but now it is mark as Cannot resolve method getSku() in Purchase
Any ideas how to solve this issues?
From docs:
Summary of changes
Added BillingClient.queryPurchasesAsync() to replace BillingClient.queryPurchases() which will be removed in a future release.
Added Purchase#getSkus() and PurchaseHistoryRecord#getSkus(). These replace Purchase#getSku and PurchaseHistoryRecord#getSku which have been removed.
But I don't know how to apply this new commands in my code above.
If I change getSku to getSkus my if if (PRODUCT_ID.equals(purchase.getSkus()) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) will say that it is always false. And I have no idea how to use queryPurchasesAsync(), need 2 params now.
Thanks.
As I mentioned earlier in a comment you are comparing a String to a List object, but as chitgoks said it is ArrayList<String> and not List<String> as i assumed. I'm not sure if you would ever get more than one sku-string (since you probably don't order multiple things at the same time?) but either look trough them all to be sure or take a chance and compare PRODUCT_ID with only purchase.getSkus().get(0).
The new async call for purchases seems to require only small changes.
Example of old way to do it:
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
doSomethingWithPurchaseList(result.getPurchasesList());
And this would be the new way to do the same:
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull List<Purchase> list) {
doSomethingWithPurchaseList(list);
}
});
So you all know new billing library has new feature
every thing will be in background thread so do not do change anything on main UI during acknowledgement of purchase and restoring purchase.
if you are giving consumable purchase then user can now buy same sku in more quantity in one purchase so write logic accordingly. use getQuantity() function.
to restore non consumable.
billingClient.queryPurchasesAsync(
BillingClient.SkuType.INAPP,
new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull List < Purchase > myPurchases) {
if (!myPurchases.isEmpty()) {
for (Object p: myPurchases) {
final Purchase purchase = (Purchase) p;
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && purchase.getSkus.contains("sku here") {
handlePurchase(purchase);
}
}
});
}
}
)
getSkus returns an ArrayList<String>. Please use contains as below.
purchase.getSkus().contains(YOUR_PRODUCT_ID.toLowerCase())