/* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠGoogle ĠLLC . ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . example . subscriptions . billing Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . app . Application Ċ import Ġandroid . arch . lifecycle . Lifecycle Ċ import Ġandroid . arch . lifecycle . Lifecycle Observer Ċ import Ġandroid . arch . lifecycle . Mutable LiveData Ċ import Ġandroid . arch . lifecycle . On Lifecycle Event Ċ import Ġandroid . util . Log Ċ import Ġcom . android . billing client . api . Billing Client Ċ import Ġcom . android . billing client . api . Billing Client State Listener Ċ import Ġcom . android . billing client . api . Billing Flow Params Ċ import Ġcom . android . billing client . api . Purchase Ċ import Ġcom . android . billing client . api . P urchases Updated Listener Ċ import Ġcom . android . billing client . api . Sku Details Ċ import Ġcom . android . billing client . api . Sku Details Params Ċ import Ġcom . android . billing client . api . Sku Details Response Listener Ċ import Ġcom . example . subscriptions . Constants Ċ import Ġcom . example . subscriptions . ui . Single Live Event Ċ Ċ class ĠBilling Client Lifecycle Ġprivate Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġapp : ĠApplication Ċ ) Ġ: ĠLifecycle Observer , ĠP urchases Updated Listener , ĠBilling Client State Listener , ĊĠĠĠĠĠĠĠ ĠSk u Details Response Listener Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġpurchase Ġevent Ġis Ġobservable . ĠOnly Ġone Ġo ber ver Ġwill Ġbe Ġnotified . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpurchase Update Event Ġ= ĠSingle Live Event < List < Purchase >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠP urchases Ġare Ġobservable . ĠThis Ġlist Ġwill Ġbe Ġupdated Ġwhen Ġthe ĠBilling ĠLibrary ĊĠĠĠĠ Ġ* Ġdetect s Ġnew Ġor Ġexisting Ġpurch ases . ĠAll Ġob servers Ġwill Ġbe Ġnotified . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpurch ases Ġ= ĠMutable LiveData < List < Purchase >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSk u Details Ġfor Ġall Ġknown ĠSK Us . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġsk us With Sku Details Ġ= ĠMutable LiveData < Map < String , ĠSk u Details >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInstantiate Ġa Ġnew ĠBilling Client Ġinstance . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġlateinit Ġprivate Ġvar Ġbilling Client : ĠBilling Client ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Billing Lifecycle " ĊĊĠĠĠĠĠĠĠ Ġ@ Volatile ĊĠĠĠĠĠĠĠ Ġprivate Ġvar ĠINSTANCE : ĠBilling Client Lifecycle ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġfun ĠgetInstance ( app : ĠApplication ): ĠBilling Client Lifecycle Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠINSTANCE Ġ?: Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠINSTANCE Ġ?: ĠBilling Client Lifecycle ( app ). also Ġ{ ĠINSTANCE Ġ= Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On Lifecycle Event ( Lifecycle . Event . ON _ CREATE ) ĊĠĠĠ Ġfun Ġcreate () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġa Ġnew ĠBilling Client Ġin ĠonCreate (). ĊĠĠĠĠĠĠĠ Ġ// ĠSince Ġthe ĠBilling Client Ġcan Ġonly Ġbe Ġused Ġonce , Ġwe Ġneed Ġto Ġcreate Ġa Ġnew Ġinstance ĊĠĠĠĠĠĠĠ Ġ// Ġafter Ġending Ġthe Ġprevious Ġconnection Ġto Ġthe ĠGoogle ĠPlay ĠStore Ġin Ġon Destroy (). ĊĠĠĠĠĠĠĠ Ġbilling Client Ġ= ĠBilling Client . newBuilder ( app . application Context ). set Listener ( this ). build () ĊĠĠĠĠĠĠĠ Ġif Ġ(! billing Client . is Ready ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Billing Client : ĠStart Ġconnection ...") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Client . start Connection ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On Lifecycle Event ( Lifecycle . Event . ON _ DESTROY ) ĊĠĠĠ Ġfun Ġdestroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( billing Client . is Ready ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Billing Client Ġcan Ġonly Ġbe Ġused Ġonce Ġ-- Ġclosing ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBilling Client Ġcan Ġonly Ġbe Ġused Ġonce . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAfter Ġcalling Ġend Connection (), Ġwe Ġmust Ġcreate Ġa Ġnew ĠBilling Client . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Client . end Connection () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Billing Setup Finished ( billing Response Code : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbilling Response Names [ billing Response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Billing Setup Finished : Ġ$ billing Response Code Ġ$ name ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( billing Response Code Ġ== ĠBilling Client . Billing Response . OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġbilling Ġclient Ġis Ġready . ĠYou Ġcan Ġquery Ġpurch ases Ġhere . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquery Sku Details () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate P urchases () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIn Ġorder Ġto Ġmake Ġpurchase se , Ġyou Ġneed Ġthe Ġ[ Sku Details ] Ġfor Ġthe Ġitem Ġor Ġsubscription . ĊĠĠĠĠ Ġ* ĠThis Ġis Ġan Ġasynchronous Ġcall Ġthat Ġwill Ġreceive Ġa Ġresult Ġin Ġ[ on Sku Details Response ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġquery Sku Details () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠSk u Details Params . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setType ( Billing Client . Sku Type . SUB S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Sk us List ( listOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠConstants . BASIC _ SK U , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠConstants . PRE MI UM _ SK U ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġparams ?. let Ġ{ Ġsku Details Params Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" query Sku Details Async ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Client . query Sku Details Async ( sku Details Params , Ġthis ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRe ceiv es Ġthe Ġresult Ġfrom Ġ[ query Sku Details ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠStore Ġthe ĠSk u Details Ġand Ġpost Ġthem Ġin Ġthe Ġ[ sk us With Sku Details ]. ĠThis Ġallows Ġother Ġparts ĊĠĠĠĠ Ġ* Ġof Ġthe Ġapp Ġto Ġuse Ġthe Ġ[ Sku Details ] Ġto Ġshow ĠSK U Ġinformation Ġand Ġmake Ġpurch ases . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Sku Details Response ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Billing Client . Billing Response Ġresponse Code : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsku Details List : ĠMutable List < Sku Details >? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( response Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . OK Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Response Names [ response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" on Sku Details Response : Ġ$ response Code Ġ$ name ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sku Details List Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" on Sku Details Response : ĠNo ĠSk u Details Ġfound ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsk us With Sku Details . post Value ( empty Map ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsk us With Sku Details . post Value ( HashMap < String , ĠSk u Details >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( details Ġin Ġsku Details List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( details . sku , Ġdetails ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. also Ġ{ Ġposted Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Sku Details Ġcount : Ġ${ posted Value . size }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . SERVICE _ DIS CONNECTED , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . SERVICE _ UN AVAILABLE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . B ILL ING _ UN AVAILABLE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . ITEM _ UN AVAILABLE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . DE VELO PER _ ERROR , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . ERROR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Response Names [ response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" on Sku Details Response : Ġ$ response Code Ġ$ name ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . USER _ C ANCE LED , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . FEATURE _ NOT _ SUPPORTED , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . ITEM _ AL READY _ OWN ED , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . ITEM _ NOT _ OWN ED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThese Ġresponse Ġcodes Ġare Ġnot Ġexpected . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Response Names [ response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w tf ( TAG , Ġ" on Sku Details Response : Ġ$ response Code Ġ$ name ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġoverride Ġfun Ġon Billing Service Disconnected () Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Billing Service Disconnected ") ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠTry Ġconnecting Ġagain Ġwith Ġexponential Ġbackoff . ĊĠĠĠĠĠĠĠ Ġ// Ġbilling Client . start Connection ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠQuery ĠGoogle ĠPlay ĠBilling Ġfor Ġexisting Ġpurch ases . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNew Ġpurch ases Ġwill Ġbe Ġprovided Ġto Ġthe ĠP urchases Updated Listener . ĊĠĠĠĠ Ġ* ĠYou Ġstill Ġneed Ġto Ġcheck Ġthe ĠGoogle ĠPlay ĠBilling ĠAPI Ġto Ġknow Ġwhen Ġpurchase Ġtokens Ġare Ġremoved . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġupdate P urchases () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! billing Client . is Ready ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Billing Client Ġis Ġnot Ġready Ġto Ġquery Ġfor Ġexisting Ġpurch ases ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġbilling Client . query P urchases ( Billing Client . Sku Type . SUB S ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Update Ġpurchase : ĠNull Ġpurchase Ġresult ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle P urchases ( null ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . p urchases List Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Update Ġpurchase : ĠNull Ġpurchase Ġlist ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle P urchases ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle P urchases ( result . p urchases List ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġby Ġthe ĠBilling ĠLibrary Ġwhen Ġnew Ġpurch ases Ġare Ġdetected . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon P urchases Updated ( response Code : ĠInt , Ġpurch ases List : ĠList < Purchase > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġbilling Response Names [ response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on P urchases Updated : Ġ$ response Code Ġ$ name ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhen Ġ( response Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . OK Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( p urchases List Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Purchase Ġupdate : ĠNo Ġpurch ases ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle P urchases ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle P urchases ( p urchases List ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . USER _ C ANCE LED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" User Ġcanceled Ġthe Ġpurchase ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . ITEM _ AL READY _ OWN ED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" The Ġuser Ġalready Ġowns Ġthis Ġitem ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBilling Client . Billing Response . DE VELO PER _ ERROR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Developer Ġerror Ġmeans Ġthat ĠGoogle ĠPlay Ġdoes Ġnot Ġrecognize Ġthe Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" configuration . ĠIf Ġyou Ġare Ġjust Ġgetting Ġstarted , Ġmake Ġsure Ġyou Ġhave Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" configured Ġthe Ġapplication Ġcorrectly Ġin Ġthe ĠGoogle ĠPlay ĠConsole . Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" The ĠSK U Ġproduct ĠID Ġmust Ġmatch Ġand Ġthe ĠA PK Ġyou Ġare Ġusing Ġmust Ġbe Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" signed Ġwith Ġrelease Ġkeys .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbilling Response Names [ response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Billing Client . Billing Response : Ġ$ response Code Ġ$ name ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġpurch ases Ġhave Ġchanged Ġbefore Ġupdating Ġother Ġpart Ġof Ġthe Ġapp . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġhandle P urchases ( p urchases List : ĠList < Purchase > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Un changed Purchase List ( p urchases List )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Same Ġ${ p urchases List ?. size } Ġpurchase ( s ), Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" no Ġneed Ġto Ġpost Ġan Ġupdate Ġto Ġthe Ġlive Ġdata ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Handling Ġ${ p urchases List ?. size } Ġpurchase ( s )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate P urchases ( p urchases List ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġwhether Ġthe Ġpurch ases Ġhave Ġchanged Ġbefore Ġposting Ġchanges . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis Un changed Purchase List ( p urchases List : ĠList < Purchase >? ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠOpt imize Ġto Ġavoid Ġupdates Ġwith Ġidentical Ġdata . ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSend Ġpurchase ĠSingle Live Event Ġand Ġupdate Ġpurch ases ĠLive Data . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe ĠSingle Live Event Ġwill Ġtrigger Ġnetwork Ġcall Ġto Ġverify Ġthe Ġsubscriptions Ġon Ġthe Ġsever . ĊĠĠĠĠ Ġ* ĠThe ĠLive Data Ġwill Ġallow ĠGoogle ĠPlay Ġsettings ĠUI Ġto Ġupdate Ġbased Ġon Ġthe Ġlatest Ġpurchase Ġdata . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġupdate P urchases ( p urchases List : ĠList < Purchase > ?) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" update P urchases : Ġ${ p urchases List ?. size } Ġpurchase ( s )") ĊĠĠĠĠĠĠĠ Ġpurchase Update Event . post Value ( p urchases List ) ĊĠĠĠĠĠĠĠ Ġpurch ases . post Value ( p urchases List ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġlaunch Billing Flow ( activity : ĠActivity , Ġparams : ĠBilling Flow Params ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsku Ġ= Ġparams . sku ĊĠĠĠĠĠĠĠ Ġval Ġold Sku Ġ= Ġparams . old Sku ĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Launch ing Ġbilling Ġflow Ġw th Ġsku : Ġ$ sku , Ġold Sku : Ġ$ old Sku ") ĊĠĠĠĠĠĠĠ Ġif Ġ(! billing Client . is Ready ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Billing Client Ġis Ġnot Ġready Ġto Ġstart Ġbilling Ġflow ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġresponse Code Ġ= Ġbilling Client . launch Billing Flow ( activity , Ġparams ) ĊĠĠĠĠĠĠĠ Ġbilling Response Names [ response Code ]. let Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Billing Response Ġfrom Ġlaunch Billing Flow (): Ġ$ response Code Ġ$ name ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresponse Code ĊĠĠĠ Ġ} Ċ Ċ } Ċ