Android Question SOLVED - Crash with new Google Billing 5.0 - offerToken

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I upgraded yesterday to the new Google Billing Library 5.00 and now I am crashing (offerToken)

Looked at the Erel's example (nothing in there for Subs - which is what I am crashing on)

Stack Trace
java.lang.NullPointerException: offerToken is required for constructing ProductDetailsParams.
at com.google.android.gms.internal.play_billing.zzm.zzc(com.android.billingclient:billing@@5.0.0:1)
at com.android.billingclient.api.BillingFlowParams$ProductDetailsParams$Builder.build(com.android.billingclient:billing@@5.0.0:2)
at anywheresoftware.b4a.objects.BillingClientWrapper.LaunchBillingFlow(BillingClientWrapper.java:262)
at com.BOBs.BBS.pbilling$ResumableSub_Query_Buy.resume(pbilling.java:760)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:207)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:6752)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Code Below
#Region Query_Buy
Public Sub Query_Buy(PurchaseFrom As String, ProductID As String) As ResumableSub

Wait For(gBillingClient.ConnectIfNeeded) Billing_Connected (Result As BillingResult)

If Result.IsSuccess Then 'get the sku details
Dim sf As Object = gBillingClient.QuerySkuDetails(PurchaseFrom, Array(ProductID))

Wait For(sf) Billing_SkuQueryCompleted(Result As BillingResult, SkuDetails As List)

If Result.IsSuccess And SkuDetails.Size = 1 Then 'start the billing process.
Result = gBillingClient.LaunchBillingFlow(SkuDetails.Get(0)) <------------------------ THIS IS THE LINE I AM Crashing On

If Result.IsSuccess Then
Return True
End If
End If
End If

Return False
End Sub
#end Region
 

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I am confused according to this link https://developer.android.com/refer...ails.SubscriptionOfferDetails#getOfferToken()
I need to pass the offer token to launchBillingFlow

So I did this
B4X:
#Region Query_Buy
Public  Sub Query_Buy(PurchaseFrom As String, ProductID As String) As ResumableSub 
    
            Wait For(gBillingClient.ConnectIfNeeded) Billing_Connected (Result As BillingResult)
    
            If     Result.IsSuccess Then    'get the sku details    
                Dim sf As Object = gBillingClient.QuerySkuDetails(PurchaseFrom, Array(ProductID))

                Wait For(sf) Billing_SkuQueryCompleted(Result As BillingResult, SkuDetails As List)
                            
                If  Result.IsSuccess And SkuDetails.Size = 1 Then    'start the billing process.
                    Dim offers         As List         = SkuDetails.Get(0).As(JavaObject).RunMethod("getSubscriptionOfferDetails", Null)
                    Dim offer         As JavaObject     = offers.Get(0)                    
                    Dim offerToken     As String         = offer.RunMethod("getOfferToken", Null)                      
                    
                    Result = gBillingClient.LaunchBillingFlow(offerToken)     ' trying to pass the offerToken but LaunchBillingFlow does not what a string but SkuDetails 'SkuDetails.Get(0))

                    If  Result.IsSuccess Then 
                        Return True
                    End If
                End If
            End If
            
            Return False    
End Sub
#end Region
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
B4X:
Public  Sub Query_Buy(PurchaseFrom As String, ProductID As String) As ResumableSub 
    
            Wait For(gBillingClient.ConnectIfNeeded) Billing_Connected(Result As BillingResult)
    
    
            If     Result.IsSuccess Then    
                    Dim sf As Object = gBillingClient.QuerySkuDetails(PurchaseFrom, Array(ProductID))

                    Wait For(sf) Billing_SkuQueryCompleted(Result As BillingResult, SkuDetails As List)
                            
                    If  Result.IsSuccess And SkuDetails.Size = 1 Then    'start the billing process.
                        Dim offers                         As List         = SkuDetails.Get(0).As(JavaObject).RunMethod("getSubscriptionOfferDetails", Null)
                        Dim offer                         As JavaObject     = offers.Get(0)                    
                        Dim offerToken                     As String         = offer.RunMethod("getOfferToken", Null)                      
'                    
                        Dim ctxt                         As JavaObject
                        Dim ProductDetailsParamsBuilder As JavaObject
                        Dim BillingFlowParamsBuilder     As JavaObject
                        Dim ProductDetails                 As List
                        
                        ctxt.InitializeContext
                        
                        ProductDetailsParamsBuilder =               ProductDetailsParamsBuilder.InitializeStatic("com.android.billingclient.api.BillingFlowParams.ProductDetailsParams").RunMethod("newBuilder", Null)
                        ProductDetailsParamsBuilder.RunMethod("setProductDetails", Array(SkuDetails.Get(0)))
                        ProductDetailsParamsBuilder.RunMethod("setOfferToken", Array(offerToken))
                        
                        ProductDetails = Array(ProductDetailsParamsBuilder.RunMethod("build", Null))
                        
                        BillingFlowParamsBuilder = BillingFlowParamsBuilder.InitializeStatic("com.android.billingclient.api.BillingFlowParams").RunMethod("newBuilder", Null)
                        BillingFlowParamsBuilder.RunMethod("setProductDetailsParamsList", Array(ProductDetails))
        
                        Result = gBillingClient.As(JavaObject).GetFieldJO("client").RunMethod("launchBillingFlow", Array(ctxt, BillingFlowParamsBuilder.RunMethod("build", Null)))
    
                        Log($"Billing Client Result:${Result.IsSuccess}"$)
        
'                        Result = gBillingClient.LaunchBillingFlow(SkuDetails.Get(0))

                        If  Result.IsSuccess Then 
                            Return True
                        End If 
                    End If
            End If
            
            Return False    
End Sub
 
Upvote 0
Top