Skip to content

Commit d7f7644

Browse files
committed
Update PreferencesBillingHelper for new API
1 parent 987ff38 commit d7f7644

1 file changed

Lines changed: 41 additions & 24 deletions

File tree

src/standard/java/com/gianlu/commonutils/preferences/PreferencesBillingHelper.java

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,47 @@
2020
import com.android.billingclient.api.BillingClientStateListener;
2121
import com.android.billingclient.api.BillingFlowParams;
2222
import com.android.billingclient.api.BillingResult;
23+
import com.android.billingclient.api.PendingPurchasesParams;
24+
import com.android.billingclient.api.ProductDetails;
2325
import com.android.billingclient.api.Purchase;
2426
import com.android.billingclient.api.PurchasesUpdatedListener;
25-
import com.android.billingclient.api.SkuDetails;
26-
import com.android.billingclient.api.SkuDetailsParams;
27+
import com.android.billingclient.api.QueryProductDetailsParams;
2728
import com.gianlu.commonutils.R;
2829
import com.gianlu.commonutils.dialogs.DialogUtils;
2930
import com.gianlu.commonutils.ui.Toaster;
3031
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
3132

32-
import java.util.Arrays;
33+
import java.util.ArrayList;
3334
import java.util.List;
3435

3536
public class PreferencesBillingHelper {
3637
private static final String TAG = PreferencesBillingHelper.class.getSimpleName();
3738
private final Object billingReady = new Object();
3839
private final DialogUtils.ShowStuffInterface listener;
39-
private final List<String> products;
40+
private final List<QueryProductDetailsParams.Product> products;
4041
private BillingClient billingClient;
4142
private boolean destroyed = false;
4243

4344
public PreferencesBillingHelper(@NonNull DialogUtils.ShowStuffInterface listener, String... products) {
4445
this.listener = listener;
45-
this.products = Arrays.asList(products);
46+
this.products = new ArrayList<>();
47+
for (String product : products) {
48+
this.products.add(QueryProductDetailsParams.Product.newBuilder()
49+
.setProductId(product)
50+
.setProductType(BillingClient.ProductType.INAPP)
51+
.build());
52+
}
4653
}
4754

4855
public void onStart(@NonNull Activity activity) {
4956
if (destroyed) throw new IllegalStateException();
5057

51-
billingClient = BillingClient.newBuilder(activity).enablePendingPurchases().setListener(new InternalListener()).build();
58+
billingClient = BillingClient.newBuilder(activity)
59+
.enablePendingPurchases(PendingPurchasesParams.newBuilder()
60+
.enableOneTimeProducts()
61+
.enablePrepaidPlans()
62+
.build())
63+
.setListener(new InternalListener()).build();
5264
billingClient.startConnection(new BillingClientStateListener() {
5365
private boolean retried = false;
5466

@@ -85,20 +97,22 @@ public void onDestroy() {
8597
}
8698
}
8799

88-
private void buyProduct(@NonNull Activity activity, @NonNull SkuDetails product) {
100+
private void buyProduct(@NonNull Activity activity, @NonNull ProductDetails product) {
89101
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
90-
.setSkuDetails(product)
102+
.setProductDetailsParamsList(List.of(BillingFlowParams.ProductDetailsParams.newBuilder()
103+
.setProductDetails(product)
104+
.build()))
91105
.build();
92106

93107
BillingResult result = billingClient.launchBillingFlow(activity, flowParams);
94108
if (result.getResponseCode() != BillingResponseCode.OK)
95109
handleBillingErrors(result.getResponseCode());
96110
}
97111

98-
private void showDonateDialog(@NonNull Activity activity, List<SkuDetails> products) {
112+
private void showDonateDialog(@NonNull Activity activity, List<ProductDetails> products) {
99113
RecyclerView list = new RecyclerView(activity);
100114
list.setLayoutManager(new LinearLayoutManager(activity, RecyclerView.VERTICAL, false));
101-
list.setAdapter(new SkuAdapter(activity, products, product -> {
115+
list.setAdapter(new ProductAdapter(activity, products, product -> {
102116
buyProduct(activity, product);
103117
listener.dismissDialog();
104118
}));
@@ -114,15 +128,12 @@ public void donate(@NonNull Activity activity, boolean wasWaiting) {
114128
listener.showDialog(DialogUtils.progressDialog(activity, R.string.connectingBillingService));
115129

116130
if (billingClient != null && billingClient.isReady()) {
117-
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
118-
params.setSkusList(products).setType(BillingClient.SkuType.INAPP);
119-
billingClient.querySkuDetailsAsync(params.build(), (billingResult, skuDetailsList) -> {
131+
billingClient.queryProductDetailsAsync(QueryProductDetailsParams.newBuilder().setProductList(products).build(), (billingResult, productDetailsList) -> {
120132
listener.dismissDialog();
121133

122134
if (billingResult.getResponseCode() == BillingResponseCode.OK)
123-
showDonateDialog(activity, skuDetailsList);
124-
else
125-
handleBillingErrors(billingResult.getResponseCode());
135+
showDonateDialog(activity, productDetailsList.getProductDetailsList());
136+
else handleBillingErrors(billingResult.getResponseCode());
126137
});
127138
} else {
128139
new Thread() {
@@ -151,7 +162,6 @@ private void handleBillingErrors(@BillingResponseCode int code) {
151162
case BillingResponseCode.BILLING_UNAVAILABLE:
152163
case BillingResponseCode.SERVICE_UNAVAILABLE:
153164
case BillingResponseCode.SERVICE_DISCONNECTED:
154-
case BillingResponseCode.SERVICE_TIMEOUT:
155165
listener.showToast(Toaster.build().message(R.string.failedBillingConnection));
156166
break;
157167
case BillingResponseCode.USER_CANCELED:
@@ -170,12 +180,12 @@ private void handleBillingErrors(@BillingResponseCode int code) {
170180
}
171181
}
172182

173-
public static class SkuAdapter extends RecyclerView.Adapter<SkuAdapter.ViewHolder> {
174-
private final List<SkuDetails> products;
183+
public static class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
184+
private final List<ProductDetails> products;
175185
private final Listener listener;
176186
private final LayoutInflater inflater;
177187

178-
SkuAdapter(Context context, List<SkuDetails> products, Listener listener) {
188+
ProductAdapter(Context context, List<ProductDetails> products, Listener listener) {
179189
this.products = products;
180190
this.listener = listener;
181191
this.inflater = LayoutInflater.from(context);
@@ -189,9 +199,9 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
189199

190200
@Override
191201
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
192-
final SkuDetails item = products.get(position);
202+
final ProductDetails item = products.get(position);
193203

194-
switch (item.getSku()) {
204+
switch (item.getProductId()) {
195205
case "donation.lemonade":
196206
holder.icon.setImageResource(R.drawable.ic_juice_64dp);
197207
break;
@@ -212,9 +222,16 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
212222
break;
213223
}
214224

225+
final String price;
226+
if (item.getOneTimePurchaseOfferDetails() != null) {
227+
price = item.getOneTimePurchaseOfferDetails().getFormattedPrice();
228+
} else {
229+
price = "???";
230+
}
231+
215232
holder.title.setText(item.getTitle());
216233
holder.description.setText(item.getDescription());
217-
holder.buy.setText(item.getPrice());
234+
holder.buy.setText(price);
218235
holder.buy.setOnClickListener(view -> {
219236
if (listener != null) listener.onItemSelected(item);
220237
});
@@ -230,7 +247,7 @@ public int getItemCount() {
230247
}
231248

232249
public interface Listener {
233-
void onItemSelected(@NonNull SkuDetails product);
250+
void onItemSelected(@NonNull ProductDetails product);
234251
}
235252

236253
class ViewHolder extends RecyclerView.ViewHolder {

0 commit comments

Comments
 (0)