Search code examples
androidplay-billing-library

Android - updating button onSkuDetailsResponse for Billing Library products


I'm setting up an interface to work with the Google Play Billing Library. I query subscription products with querySkuDetailsAsync and then I cycle through the products returned so I can enable purchase buttons.

This is the script I'm using

billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
            
            if (!list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    
                    if (list.get(i).getSku().equals("core_monthly")) {
                        monthlyDetails = list.get(i);
                        

                    } else if (list.get(i).getSku().equals("core_annual")) {
                        annualDetails = list.get(i);
                        
                    }
                }

                monthlySubscribe.setEnabled(true);
                annualSubscribe.setEnabled(true);
                monthlySubscribe.setText("Monthly Subscription");
                annualSubscribe.setText("Annual Subscription");

            } else {
                Toast.makeText(getActivity(), "There was a problem getting available plans", Toast.LENGTH_SHORT);
            }
        }
    });

The problem is that setText() the button texts are never updated. How can I update the button names and enable them after I get the products?


Solution

  • The reason why .setText() doesn't work is because billingClient method is called in a background thread, as your log shows: Thread: PlayBillingLibrary-2. Anything related to the UI must be called in the main thread.

    To solve this you have to do something like this:

    Add this method to your project:

    private Handler findUiHandler() {
            return new Handler(Looper.getMainLooper());
        }
    

    And then, whenever you want to update the UI and the thread isn't main thread, call your code like this:

     findUiHandler().post(() -> {
                    //here is the code that needs to be executed on the main thread
                    monthlySubscribe.setEnabled(true);
                    annualSubscribe.setEnabled(true);
                    monthlySubscribe.setText("Monthly Subscription");
                    annualSubscribe.setText("Annual Subscription");
                });