1

I am new to the implementation of Google's Billing library and using this system to make subscriptions inside my app. I am trying to get the title of skuDetailsList which is obtained from onSkuDetailsResponse and adding to the ArrayList dataSource. I am setting the ArraryList as datasource to the adapter . The issue is the ListView is getting displayed empty every time even though there are items available in the ArrayList DataSource.

I tried adding dummy values to the datasource and found that they are getting displayed in the list view control. So, i have I debugged the code and found that the view is getting returned first and then the items are getting added to the ArrayList Datasource as onSkuDetailsResponse is getting called asynchronously.

Following is the entire code used for establishing connection, getting the SKU Details , binding it array list and setting the adapter to the ListView Control in "OnCreateView"

Code for Establishing connection

private void startBillingServiceConnection(){
        //Initialize a billing client
        billingClient = BillingClient.newBuilder(this.getActivity())
                .setListener(this)
                .enablePendingPurchases()
                .build();
        //Establish a connection to Google Play
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {

                    // The BillingClient is ready. You can query purchases here....
                    querySkuDetails();                        
                }
            }
            @Override
            public void onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
            }
        });
    }

Code for querySkDetails

public void querySkuDetails() {
        Log.i(TAG, "querySkuDetails");

        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
        params.setSkusList(LIST_OF_SKUS).setType(BillingClient.SkuType.SUBS);
        billingClient.querySkuDetailsAsync(params.build(),
                new SkuDetailsResponseListener() {
                    @Override
                    public void onSkuDetailsResponse(BillingResult billingResult,
                                                     List<SkuDetails> skuDetailsList) {
                        if (billingResult == null) {
                            return;
                        }
                        int responseCode = billingResult.getResponseCode();
                        String debugMessage = billingResult.getDebugMessage();
                        switch (responseCode) {
                            case BillingClient.BillingResponseCode.OK:
                                if (skuDetailsList != null && skuDetailsList.size() > 0) {
                                    subscribeItemDisplay.clear();
                                    for (SkuDetails p : skuDetailsList) {
                                        subscribeItemDisplay.add("Product Name - "+p.getOriginalPrice()+": "+p.getSubscriptionPeriod()+": "+p.getFreeTrialPeriod());
                                    }
                                }
                            
                            default:                                    
                                break;
                        }
                    }
                });
    }

Code in "OnCreateView"

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainHandler = new Handler();

        // Inflate layout
        View view = inflater.inflate(R.layout.subscribe_fragment, container, false);            
        subscriptionsListView = view.findViewById(R.id.subscriptionsView);            
        loadInAppProductIDS();            
        return view;
    }

Code for loadInAppProductIDS

public void loadInAppProductIDS() {

        new Thread(new Runnable() {
            @Override
            public void run() {
                LIST_OF_SKUS= Collections.unmodifiableList(myProductIDs);
                startBillingServiceConnection();
                mainHandler.post(new Runnable() {
                    public void run() {
                        arrayAdapter = new ArrayAdapter<String>(getActivity(), R.layout.subscription_items_list, subscribeItemDisplay);
                        subscriptionsListView.setAdapter(arrayAdapter);
                    }
                });
            }
        }).start();
    }

Can you please suggest on how to add items to datasource, bind to the list view and then return the view?

Kamal
  • 453
  • 1
  • 10
  • 22

3 Answers3

0

The problem is you are setting adapter in beginning before list are loaded from onSkuDetailsResponse, You should just set adapter after you receive data. So your code should be like this:

View view = inflater.inflate(R.layout.subscribe_fragment, container, false);
---- Code here for establishing the connection to Google Play and querying skuDetails in the onBillingSetupFinished method ----
subscriptionsListView = view.findViewById(R.id.subscriptionsView);

return view;

and your onSkuDetailResponse should be like this:

public void onSkuDetailsResponse(BillingResult billingResult,
                                 List<SkuDetails> skuDetailsList) {
    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
        if (skuDetailsList != null && skuDetailsList.size() > 0) {
            subscribeItemDisplay.clear();
            for(SkuDetails p:skuDetailsList){
                subscribeItemDisplay.add(p.getTitle());
            }
            arrayAdapter = new ArrayAdapter<String>(this.getActivity(),
                    R.layout.subscribtion_item_list, subscribeItemDisplay);
            subscriptionsListView.setAdapter(arrayAdapter);
        }
    }
}
Keyur Nimavat
  • 3,595
  • 3
  • 13
  • 19
  • I already tried this code earlier itself but i am getting problem with loading the list view at the beginning . Once i close the view and re-load it again then i can see the SKU Details in the list view.. Getting problems with loading the SKUdetails for the first time – Kamal Jul 26 '21 at 04:00
  • If both view are same then it should not be an issue. You should show your full code where are you calling for sku details and where are you showing in list? – Keyur Nimavat Jul 27 '21 at 18:25
  • I have edited my question with all the required details. Please check and provide me a solution to bind the products to the list view control – Kamal Jul 28 '21 at 04:08
  • your code is still wrong. not as per given solution. You are calling startBillingServiceConnection(); and then inside handler you are trying to set adapter. It will not work. You must set adapter inside onSkuDetailsResponse after for loop as I given in solution. – Keyur Nimavat Jul 31 '21 at 08:49
  • I have already tried setting the adapter inside onSkuDetailsResponse but everytime empty list is getting displayed for the list view control – Kamal Aug 02 '21 at 06:44
0

In your ListView adapter create this method which add data to the listView.

public void add(String title) {
    titleLists.add(title)
    notifyItemInserted(titleLists.size - 1)
}

in your activity class call add() function.

if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        if (skuDetailsList != null && skuDetailsList.size() > 0) 
                        {
                            subscribeItemDisplay.clear();
                            for(SkuDetails p:skuDetailsList){
                                subscribeItemDisplay.add(p.getTitle());
                                arrayAdapter.add(p.getTitle());
                            }
                        }
                    }
Yahya M
  • 392
  • 3
  • 13
0

You can notify adapter after list filled.

public void onSkuDetailsResponse(BillingResult billingResult,
                                                     List<SkuDetails> skuDetailsList) {
                        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                            if (skuDetailsList != null && skuDetailsList.size() > 0) {
                                subscribeItemDisplay.clear();
                                for(SkuDetails p:skuDetailsList){
                                    subscribeItemDisplay.add(p.getTitle());
                                }
                                notifyDataSetChanged();
                            }
                        }
                    }
Vaibhav K
  • 43
  • 2
  • 12