Android Kotlin APP 應用程式內購買In-App Billing with Google ...

文章推薦指數: 80 %
投票人數:10人

完成設定且建立好商品的人應該可以在Google Play Console 看到以下畫面 ... APP 內購,Google Play In-App billing. implementation ... 關閉廣告 Willy'sFish教學筆記』 跳到主文 授人以魚,不如授人以漁 部落格全站分類:數位生活 相簿 部落格 留言 名片 Jul20Mon202017:33 AndroidKotlinAPP應用程式內購買In-AppBillingwithGooglePlayBillingLibrary實作教學、範例example(similariOSInAppPurchase)(一)』Willy'sFish教學筆記 我們發佈APP有很大的一份部就是為了賺錢吧 那麼就不可不知,如何實作APP內購功能 無論是一次性的遊戲藥水,還是週期性的訂閱服務 用2019 GoogleIO推出的GooglePlayBillingLibrary一次做給你看   在開始之前我們有一些程式外的資訊需要設定 1、取得開發者帳號 2、在GooglePlayConsole設定付款資訊(金流用的) 3、把 1&2 關聯起來 https://developer.android.com/google/play/billing/getting-ready#account 4、在 GooglePlayConsole建立商品(需先上傳有權限apk) https://support.google.com/googleplay/android-developer/answer/1153481   以上跟著Google的引導做,應該就可以了 完成設定且建立好商品的人應該可以在GooglePlayConsole看到以下畫面     再來就是APP這裡要開始實作Library了 首先要有內購的權限,在manifast加入下列   在app/gradledependencies加入依賴  //APP內購,GooglePlayIn-Appbilling. implementation'com.android.billingclient:billing-ktx:3.0.0'   rebuild之後,我們來寫一個lifecycleobserver 用來管理BillingClient的生命週期 classBillingClientLifecycleprivateconstructor( privatevalapp:Application ):LifecycleObserver, PurchasesUpdatedListener, BillingClientStateListener{ privatelateinitvarbillingClient:BillingClient companionobject{ @Volatile privatevarINSTANCE:BillingClientLifecycle?=null fungetInstance(app:Application):BillingClientLifecycle= INSTANCE?:synchronized(this){ INSTANCE?:BillingClientLifecycle(app) .also{INSTANCE=it} } }   可以看到我們用singleton來生成這個class 並impletment  LifecycleObserver,PurchasesUpdatedListener,BillingClientStateListener   然後 LifecycleObserver這邊的onCreate實作如下 @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) funcreate(){ PLog.d("$TAG:ON_CREATE") billingClient=BillingClient .newBuilder(app.applicationContext) .setListener(this) .enablePendingPurchases()//Notusedforsubscriptions. .build() if(!billingClient.isReady){ PLog.d("$TAG:BillingClient:Startconnection...") billingClient.startConnection(this) } }   在onCreate我們做了連線至BillingLibrary的動作 所以相對的,我們也會在onDestory進行disconnection @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fundestroy(){ PLog.d("$TAG:ON_DESTROY") if(billingClient.isReady){ PLog.d("$TAG:closingconnection") //AftercallingendConnection()  //wemustcreateanewBillingClient. billingClient.endConnection() } }   這樣就控制住了連線與斷線 再來我們就可以利用 BillingClientStateListener做事情 比如說:連線後查詢or斷線後重連 /**===BillingClientStateListenerStart===*/ overridefunonBillingSetupFinished(  billingResult:BillingResult){ valresponseCode=billingResult.responseCode valdebugMessage=billingResult.debugMessage PLog.d("$TAG:  onBillingSetupFinished:$responseCode$debugMessage") if(responseCode==BillingClient.BillingResponseCode.OK){ //Thebillingclientisready. GlobalScope.launch(Dispatchers.IO){ try{ querySkuDetails() queryPurchases() }catch(e:Throwable){ PLog.e(e,"$TAGquery:") }finally{ this.cancel() } } } } overridefunonBillingServiceDisconnected(){ PLog.d("$TAG:onBillingServiceDisconnected") //Tryconnectingagainwithexponentialbackoff. billingClient.startConnection(this) } /**===BillingClientStateListenerEnd===*/   一切都設設定好之後 就來看看怎麼query吧 suspendfunquerySkuDetails(){ PLog.d("$TAG:querySkuDetails") valparams=SkuDetailsParams.newBuilder() .setType(BillingClient.SkuType.SUBS) .setSkusList( listOf(SKU.Test001.id,SKU.Test002.id) ).build() valskuDetailsResult=withContext(Dispatchers.IO){ billingClient.querySkuDetails(params) } valbillingResult=skuDetailsResult.billingResult valresponseCode=billingResult.responseCode valdebugMessage=billingResult.debugMessage PLog.d("$TAG:  onSkuDetailsResponse:$responseCode$debugMessage") PLog.obj(skuDetailsResult) when(responseCode){ BillingClient.BillingResponseCode.OK->{ skuDetailsResult.skuDetailsList?.also{ skusWithSkuDetails.postValue( HashMap().apply{ it.forEach{ put(it.sku,it) } }.also{ PLog.d("$TAG:onSkuDetailsResponse:  count${it.size}") } ) }?:also{ PLog.d("$TAG:onSkuDetailsResponse:  nullSkuDetailslist") skusWithSkuDetails.postValue(emptyMap()) } } BillingClient.BillingResponseCode.SERVICE_DISCONNECTED, BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE, BillingClient.BillingResponseCode.BILLING_UNAVAILABLE, BillingClient.BillingResponseCode.ITEM_UNAVAILABLE, BillingClient.BillingResponseCode.DEVELOPER_ERROR, BillingClient.BillingResponseCode.ERROR->{ PLog.e("$TAG:onSkuDetailsResponse:  $responseCode$debugMessage") } BillingClient.BillingResponseCode.USER_CANCELED, BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED, BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED, BillingClient.BillingResponseCode.ITEM_NOT_OWNED->{ //Theseresponsecodesarenotexpected. PLog.d("$TAG:onSkuDetailsResponse:  $responseCode$debugMessage") } } }   附註: SKU是我用來記錄商品ID的一個enumclass SkuTpye有兩種IN_APP &SUBS skusWithSkuDetails是用來通知更新UI的LiveData   至此,我們完成了第一階段取得商品的部份 再來就可以進入下一階段,啟動購買流程囉! AndroidKotlinAPP應用程式內購買In-AppBillingwithGooglePlayBillingLibrary實作教學、範例example(similariOSInAppPurchase)(二 )』Willy'sFish教學筆記   若有遇到商品列表為空的朋友們 可以看這一篇 AndroidKotlin 實作教學/範例APP應用程式內購買In-AppBillingwithGooglePlayBillingLibrary((Q:WhydosemyListofSkuDetailreturnemptyfromgoogle?』Willy'sFish教學筆記       資料來源: https://developer.android.com/google/play/billing https://github.com/android/play-billing-samples     文章標籤 Android Kotlin APP 內購 GooglePlay GooglePlayBilling GooglePlayBillingLibrary iOS Purchase InAppPurchase 全站熱搜 創作者介紹 顏澤偉 Willy'sFish教學筆記』 顏澤偉發表在痞客邦留言(0)人氣() E-mail轉寄 全站分類:進修深造個人分類:Kotlin此分類上一篇:KotlinJava的泛型method在Kotlin中如何實作?為什麼會有Error:Cannotuse'T'reifiedtypeparameter.?HowtousetheKotlintomakeafunctionofgenericsjustlikeJava?』Willy'sFish教學筆記 上一篇:Androidapk安裝後桌面沒有啟動圖示(隱藏?),NotshowlaunchiconandnotcreatetheshortcutonthedesktopafterinstallingfromAPK』Willy'sFish教學筆記 下一篇:AndroidKotlinAPP應用程式內購買In-AppBillingwithGooglePlayBillingLibrary實作教學、範例example((Q:WhydosemyListofSkuDetailreturnemptyfromgoogle?』Willy'sFish教學筆記 ▲top 留言列表 發表留言 參觀人氣 本日人氣: 累積人氣: 文章搜尋 文章分類 程式設計(14) SVN(1)Python(2)Vue(2)Kotlin(2)ReactNative(4)純筆記(3)iOS(5)Java(3)MySQL(4)Mac(2)Git(8)Linux(3)PHP(5)Android(117) 投資理財(1) 程式人的理財筆記(1) Meditation冥想日誌(1) Meditation冥想日誌(2) 未分類文章(8) 贊助商連結 贊助商連結 熱門文章 最新文章 文章精選 文章精選 2021四月(2) 2021三月(1) 2020十二月(2) 2020十一月(2) 2020十月(1) 2020九月(2) 2020八月(1) 2020七月(3) 2020六月(1) 2020五月(1) 2020四月(2) 2020一月(3) 2019十二月(4) 2019十一月(6) 2019十月(1) 2019八月(2) 2019七月(11) 2019六月(8) 2019五月(3) 2019四月(8) 2019三月(5) 2019一月(2) 2018十二月(2) 2018十一月(6) 2018十月(7) 2018九月(1) 2018八月(1) 2018七月(1) 2018六月(1) 2018五月(1) 2018四月(1) 2017八月(7) 2017七月(5) 2017六月(7) 2017五月(5) 2017四月(7) 2017三月(15) 2017二月(6) 2017一月(14) 2016十二月(6) 2016十一月(8) 所有文章列表 新聞交換(RSS) POWEREDBY (登入) 回到頁首 回到主文 免費註冊 客服中心 痞客邦首頁 ©2003-2022PIXNET 關閉視窗



請為這篇文章評分?