首页 > 解决方案 > 用户购买时如何刷新活动?

问题描述

我有一个用于用户购买时的对话框片段。从 MainActivity 打开片段,如下所示:

DialogPurchasePizza dialogPurchasePizza = new DialogPurchasePizza(getApplicationContext());

dialogPurchasePizza.show(getSupportFragmentManager(), "Pizza Dialog");

这是对话片段:

public class DialogPurchasePizza extends AppCompatDialogFragment implements PurchasesUpdatedListener {

    private BillingClient billingClient;
    private final List<String> skuList = new ArrayList<>();
    private final String sku = "com.goodweathercorp.perappbrightness.pizzafordev";

    Button noButton;
    Button buyButton;

    Context context;

    public DialogPurchasePizza(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { // Called when making a purchase

        setRetainInstance(true); //Dialog is not killed on screen orientation change, just paused and reused.

        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity(), R.style.MaterialAlertDialog_rounded);

        LayoutInflater inflater = requireActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.purchase_dialog, null);
        builder.setView(view);

        skuList.add(sku); //add all purchases to the list

        noButton = view.findViewById(R.id.noButton);
        buyButton = view.findViewById(R.id.buyButton);
        buyButton.setEnabled(false); //set it to disabled at first until the BillingClient is ready


        MaterialToolbar purchaseToolbar = view.findViewById(R.id.purchaseToolbar);
        TextView reset_title = purchaseToolbar.findViewById(R.id.titleTextView);
        reset_title.setText(R.string.pizza_for_dev);
        reset_title.setTextColor(Color.WHITE);

        setupBillingClient(context);

        noButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        return builder.create();
    }

    private void setupBillingClient(Context c) { //connect to google play
        billingClient = BillingClient.newBuilder(c)
                .enablePendingPurchases()
                .setListener(this)
                .build();
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    //The BillingClient is setup successfully
                    loadAllSkus();
                }
            }

            @Override
            public void onBillingServiceDisconnected() {
                //TODO: implement retry logic to handle lost connections to Google Play by calling startConnection() again
            }
        });
    }

    private void loadAllSkus() {
        if (billingClient.isReady()) { //first check if BillingClient is ready
            final SkuDetailsParams params = SkuDetailsParams.newBuilder()
                    .setSkusList(skuList)
                    .setType(BillingClient.SkuType.INAPP)
                    .build();

            billingClient.querySkuDetailsAsync(params, new SkuDetailsResponseListener() {
                @Override
                public void onSkuDetailsResponse(@NonNull final BillingResult billingResult, @Nullable List<SkuDetails> skuDetailsList) {
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        assert skuDetailsList != null;
                        for (Object skuDetailsObject : skuDetailsList) {
                            final SkuDetails skuDetails = (SkuDetails) skuDetailsObject;
                            if (skuDetails.getSku().equals(sku)) { //if it found the sku in play store you can start billing flow
                                Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP); //use play store cache, no network
                                List<Purchase> purchases = result.getPurchasesList();
                                boolean isOwned = false;

                                if (purchases != null) //first check if he has already purchased
                                    for (Purchase purchase : purchases) {
                                        String thisSKU = purchase.getSku();
                                        if (thisSKU.equals(sku)) {
                                            isOwned = true;
                                            break;
                                        }
                                    }

                                if (!isOwned) {
                                    buyButton.setEnabled(true);
                                    buyButton.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            BillingFlowParams billingFlowParams = BillingFlowParams
                                                    .newBuilder()
                                                    .setSkuDetails(skuDetails)
                                                    .build();

                                            if (getActivity() != null)
                                                billingClient.launchBillingFlow(getActivity(), billingFlowParams);
                                            dismiss();
                                        }
                                    });
                                }
                            }
                            /* else if (skuDetails.getSku().equals("something else")) { //add other products

                            }*/
                        }
                    }
                }
            });
        } else Toast.makeText(context, R.string.billing_not_ready, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
        int responseCode = billingResult.getResponseCode();

        if (responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
            for (Purchase purchase : purchases) {
                handlePurchase(purchase); //acknowledge the purchase
            }
        } else if (responseCode == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
            Toast.makeText(context, R.string.item_already_owned, Toast.LENGTH_LONG).show();
        } else if (responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
            Toast.makeText(context, R.string.user_cancelled, Toast.LENGTH_LONG).show();
        }
    }

    private void handlePurchase(Purchase purchase) {
        if (purchase.getSku().equals(sku) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            if (!purchase.isAcknowledged()) {
                AcknowledgePurchaseParams acknowledgePurchaseParams =
                        AcknowledgePurchaseParams.newBuilder()
                                .setPurchaseToken(purchase.getPurchaseToken())
                                .build();
                billingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
                    @Override
                    public void onAcknowledgePurchaseResponse(@NonNull BillingResult billingResult) {
                        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                            Toast.makeText(context, R.string.purchase_done, Toast.LENGTH_LONG).show();
                            SharedPreferences pizza2 = context.getSharedPreferences("pizzaConfig", Context.MODE_PRIVATE);
                            SharedPreferences.Editor editor = pizza2.edit();
                            editor.putBoolean("purchased_right_now", true);
                            editor.apply();
                            Intent refresh = new Intent(context, MainActivity.class);
                            refresh.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); //clears previous activities
                            startActivity(refresh);
                        }
                    }
                });
            }
        }
    }

}

重要的部分在片段的最后一个方法中,handlePurchase(Purchase purchase). 我打算在这里发生的是,当确认购买时,会显示一个 Toast,告诉用户购买完成,然后重新创建主要活动。奇怪的问题是 Toast 已成功显示,但未重新创建活动。我在多个设备上对此进行了测试并得到了相同的结果。更重要的是测试这个问题非常困难,因为它需要创建一个全新的 Gmail 帐户并将其添加到游戏控制台,每次我想模拟一个购买确认时。那么为什么没有重新创建主要活动呢?

标签: javaandroid

解决方案


推荐阅读