完成設定且建立好商品的人應該可以在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
關閉視窗