Search code examples
androidin-app-billing

How to implement SkuDetailsResponseListener for in-app billing?


I want to include in-app billing in my Android app. When reading the documentation it says to:

"specify a listener which implements the SkuDetailsResponseListener interface. You can then override onSkuDetailsResponse() which notifies the listener when the query finishes"

public class MainActivity extends AppCompatActivity implements SkuDetailsResponseListener {

Which gives:

@Override
    public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {

    }

However, this is a problem because it doesn't include the listener specified in the documentation, ie.

billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    });

When including the BillingClient line and the listener there is obviously a resolve symbol error as it is outside any method, so how do you work around this?

Additionally, would you then place this block inside onCreate()?

List<String> skuList = new ArrayList<> ();
skuList.add("coins5");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);

Solution

  • As documented in Billing API documentation, you also need to implement the BillingClientStateListener as well as PurchaseUpdateListener. https://developer.android.com/google/play/billing/integrate The following code is a working example in Billing API 3.0 with Android Version Targeted SDK 28. The code is defined in a Singleton class so it can be used from multiple activities with one instance of BillingClient.

         public class ApplicationBillingClient
           {
               static ApplicationBillingClient applicationBillingClient= null;
               private static BillingClient billingClient;
    
              private ApplicationBillingClient() {}
    
              private static boolean isInitialized()
         {
        return applicationBillingClient != null && billingClient != null;
    }
    
    private static void initialize(Context applicationContext)
    {
        try
        {
            if(applicationContext != null)
            {
                applicationBillingClient = new ApplicationBillingClient();
                BillingClient.Builder builder=  BillingClient.newBuilder(applicationContext);
                builder.setListener(new PurchaseActivityListener());
                builder.enablePendingPurchases();
                billingClient = builder.build();
            }
    
            LogUtil.info("Initializing the Billing Client");
    
        }
        catch (Exception ex)
        {
            LogUtil.error("Error while initializing billing client", ex);
        }
    
    }
    
    public static ApplicationBillingClient getInstance(Context applicationContext)
    {
        if(isInitialized() == false)
        {
            initialize(applicationContext);
        }
    
        return  applicationBillingClient;
    }
    
    public void startConnection()
    {
       billingClient.startConnection(new StateListener());
    }
    
    public boolean isReady()
    {
        return billingClient.isReady();
    }
    
    public void getMonthlySubscription()
    {
        try
        {
            if(billingClient.isReady())
            {
                SkuDetailsParams.Builder skuBuilder = SkuDetailsParams.newBuilder();
                skuBuilder.setType(BillingClient.SkuType.SUBS);
                skuBuilder.setSkusList(Arrays.asList(new String[]{MONTHLY_BILLING_SUBSCRIPTION_SKU}));
                SkuDetailsParams params = skuBuilder.build();
                billingClient.querySkuDetailsAsync(params, new SkuDetailsListener());
            }
    
        }
            catch (Exception ex)
        {
            LogUtil.error("Error while querying async SKU for Monthly Subscription", ex);
        }
      }
     }
    
     //In your activity
     ApplicationBillingClient appBillingClient = 
     ApplicationBillingClient.getInstance(applicationContext);
            if (appBillingClient.isReady() == false)
            {
                appBillingClient.startConnection();
            }
            else
            {
               appBillingClient.getMonthlySubscription();
            }