Android Question Problem with GoogleBilling library 3 in new app due to Google restriction

hatzisn

Well-Known Member
Licensed User
Longtime User
Good morning everyone,

I am developing a new app and I noticed there is a problem to use it. Trying the in app purchases I keep getting in the "Test card, always approved" the "Item unavailable in your country". All subscriptions are set as available in my country as well as the app. I searched the internet for this problem and there are some voices that say that it is related to what is mentioned in the following article at the top. That is: "Reminder: Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer."


@Erel can you please upgrade the code to GoogleBilling library 4?
 

hatzisn

Well-Known Member
Licensed User
Longtime User
Hi, I get this error:

in Result = billing.LaunchBillingFlow(SkuDetails.Get(0))

Error occurred on line: 169 (InAppPurchases)
java.lang.NullPointerException: offerToken is required for constructing ProductDetailsParams.
at com.google.android.gms.internal.play_billing.zzm.zzc(com.android.billingclient:[email protected]@5.0.0:1)
at com.android.billingclient.api.BillingFlowParams$ProductDetailsParams$Builder.build(com.android.billingclient:[email protected]@5.0.0:2)
at anywheresoftware.b4a.objects.BillingClientWrapper.LaunchBillingFlow(BillingClientWrapper.java:262)
at dhqi.ttw.inapppurchases$ResumableSub_PurchaseProduct.resume(inapppurchases.java:1867)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at anywheresoftware.b4a.shell.Shell.runGoodChain(Shell.java:475)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:293)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
 
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
Does it happen with a subscription item?
Hi @Erel Yes with a subscription

*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (firebasemessaging) Create ***
** Service (firebasemessaging) Start **
Query completed: true
** Activity (main) Pause, UserClosed = false **
** Activity (act_scegli_segno) Create, isFirst = true **
** Activity (act_scegli_segno) Resume **
Error occurred on line: 181 (act_scegli_segno)
java.lang.NullPointerException: offerToken is required for constructing ProductDetailsParams.
at com.google.android.gms.internal.play_billing.zzm.zzc(com.android.billingclient:[email protected]@5.0.0:1)
at com.android.billingclient.api.BillingFlowParams$ProductDetailsParams$Builder.build(com.android.billingclient:[email protected]@5.0.0:2)
at anywheresoftware.b4a.objects.BillingClientWrapper.LaunchBillingFlow(BillingClientWrapper.java:262)
at app.moon.it.act_scegli_segno$ResumableSub_btn_acquista_Click.resume(act_scegli_segno.java:574)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at anywheresoftware.b4a.shell.Shell.runGoodChain(Shell.java:475)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:293)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
** Service (starter) Destroy (ignored)**
** Activity (act_scegli_segno) Pause, UserClosed = true **
** Service (firebasemessaging) Destroy **
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Start with this sub instead of client.LaunchBillingFlow:

B4X:
Private Sub LaunchBillingFlow (Client As BillingClient, Sku As SkuDetails, OfferToken As String) As BillingResult
    Dim ctxt As JavaObject
    ctxt.InitializeContext
    Dim ProductDetailsParamsBuilder As JavaObject
    ProductDetailsParamsBuilder = ProductDetailsParamsBuilder.InitializeStatic("com.android.billingclient.api.BillingFlowParams.ProductDetailsParams").RunMethod("newBuilder", Null)
    ProductDetailsParamsBuilder.RunMethod("setProductDetails", Array(Sku))
    ProductDetailsParamsBuilder.RunMethod("setOfferToken", Array(OfferToken))
    Dim ProductDetails As List = Array(ProductDetailsParamsBuilder.RunMethod("build", Null))
    
    Dim BillingFlowParamsBuilder As JavaObject
    BillingFlowParamsBuilder = BillingFlowParamsBuilder.InitializeStatic("com.android.billingclient.api.BillingFlowParams").RunMethod("newBuilder", Null)
    BillingFlowParamsBuilder.RunMethod("setProductDetailsParamsList", Array(ProductDetails))
    
    Return Client.As(JavaObject).GetFieldJO("client").RunMethod("launchBillingFlow", Array(ctxt, BillingFlowParamsBuilder.RunMethod("build", Null)))
End Sub

offer token is explained here: https://developer.android.com/refer...arams.Builder#setOfferToken(java.lang.String)
 
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
Start with this sub instead of client.LaunchBillingFlow:
B4X:
Private Sub LaunchBillingFlow (Client As BillingClient, Sku As SkuDetails, OfferToken As String) As BillingResult
    Dim ctxt As JavaObject
    ctxt.InitializeContext
    Dim ProductDetailsParamsBuilder As JavaObject
    ProductDetailsParamsBuilder = ProductDetailsParamsBuilder.InitializeStatic("com.android.billingclient.api.BillingFlowParams.ProductDetailsParams").RunMethod("newBuilder", Null)
    ProductDetailsParamsBuilder.RunMethod("setProductDetails", Array(Sku))
    ProductDetailsParamsBuilder.RunMethod("setOfferToken", Array(OfferToken))
    Dim ProductDetails As List = Array(ProductDetailsParamsBuilder.RunMethod("build", Null))
 
    Dim BillingFlowParamsBuilder As JavaObject
    BillingFlowParamsBuilder = BillingFlowParamsBuilder.InitializeStatic("com.android.billingclient.api.BillingFlowParams").RunMethod("newBuilder", Null)
    BillingFlowParamsBuilder.RunMethod("setProductDetailsParamsList", Array(ProductDetails))
 
    Return Client.As(JavaObject).GetFieldJO("client").RunMethod("launchBillingFlow", Array(ctxt, BillingFlowParamsBuilder.RunMethod("build", Null)))
End Sub

offer token is explained here: https://developer.android.com/refer...arams.Builder#setOfferToken(java.lang.String)

Yes it works

B4X:
Result = LaunchBillingFlow(Starter.billing, SkuDetails.Get(0), "")
 
Upvote 0

hatzisn

Well-Known Member
Licensed User
Longtime User
The launchbillingflow works but I get again in the "Test card, always approved" the "Item unavailable in your country". I cannot figure out what is wrong but I will look at it.

How can I get the OfferTokens? I tried with the following code and it did not succeed:

B4X:
            Dim jo As JavaObject
            jo = SkuDetails.Get(0)
            Dim l As List = jo.RunMethod("getSubscriptionOfferDetails", Null)
            LogColor(l, Colors.Green)

It did not work.

I have got:
(ArrayList) [com.an[email protected]1e65ae1]

What can I do?
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Last edited:
Upvote 0

hatzisn

Well-Known Member
Licensed User
Longtime User
Article about subscriptions: https://qonversion.io/blog/google-play-billing-library-5-0/

B4X:
Dim offers As List = SkuDetails.Get(0).As(JavaObject).RunMethod("getSubscriptionOfferDetails", Null)
Dim offer As JavaObject = offers.Get(0)
Log(offer.RunMethod("getOfferToken", Null))
Log(offer.RunMethod("getOfferTags", Null))
Log(offer.RunMethod("getPricingPages", Null))


Hi, according to the article I changed the last Log to the following:
Log(offer.RunMethod("getPricingPhases", Null))
 
Upvote 0
Top