인 앱 결제 추가
This commit is contained in:
parent
f0a8ca5823
commit
2101cdeb86
|
@ -40,8 +40,8 @@ android {
|
|||
applicationId "kr.co.vividnext.sodalive"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 41
|
||||
versionName "1.8.16"
|
||||
versionCode 46
|
||||
versionName "1.8.21"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
|
|
@ -85,7 +85,9 @@
|
|||
<activity android:name=".settings.terms.TermsActivity" />
|
||||
<activity android:name=".user.find_password.FindPasswordActivity" />
|
||||
<activity android:name=".mypage.can.status.CanStatusActivity" />
|
||||
<activity android:name=".mypage.can.charge.CanChargeActivity" />
|
||||
<activity
|
||||
android:name=".mypage.can.charge.CanChargeActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden" />
|
||||
<activity android:name=".mypage.can.payment.CanPaymentActivity" />
|
||||
<activity android:name=".mypage.can.coupon.CanCouponActivity" />
|
||||
<activity android:name=".live.room.create.LiveRoomCreateActivity" />
|
||||
|
|
|
@ -41,7 +41,8 @@ class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>(
|
|||
false
|
||||
)
|
||||
|
||||
changeFragment(IAP_TAG_KEY)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fl_container, CanChargeIapFragment()).commit()
|
||||
}
|
||||
|
||||
override fun setupView() {
|
||||
|
@ -59,13 +60,18 @@ class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>(
|
|||
val tabs = binding.tabs
|
||||
|
||||
tabs.visibility = View.VISIBLE
|
||||
tabs.addTab(tabs.newTab().setText("인 앱 결제").setTag(IAP_TAG_KEY))
|
||||
tabs.addTab(tabs.newTab().setText("PG").setTag(PG_TAG_KEY))
|
||||
tabs.addTab(tabs.newTab().setText("인 앱 결제"))
|
||||
tabs.addTab(tabs.newTab().setText("PG"))
|
||||
|
||||
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
val tag = tab.tag as String
|
||||
changeFragment(tag)
|
||||
when (tab.position) {
|
||||
0 -> supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fl_container, CanChargeIapFragment()).commit()
|
||||
|
||||
1 -> supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fl_container, CanChargePgFragment()).commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) {
|
||||
|
@ -79,33 +85,6 @@ class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>(
|
|||
}
|
||||
}
|
||||
|
||||
private fun changeFragment(tag: String) {
|
||||
val fragmentManager = supportFragmentManager
|
||||
val fragmentTransaction = fragmentManager.beginTransaction()
|
||||
|
||||
val currentFragment = fragmentManager.primaryNavigationFragment
|
||||
if (currentFragment != null) {
|
||||
fragmentTransaction.hide(currentFragment)
|
||||
}
|
||||
|
||||
var fragment = fragmentManager.findFragmentByTag(tag)
|
||||
if (fragment == null) {
|
||||
fragment = if (tag == PG_TAG_KEY) {
|
||||
CanChargePgFragment()
|
||||
} else {
|
||||
CanChargeIapFragment()
|
||||
}
|
||||
|
||||
fragmentTransaction.add(R.id.fl_container, fragment, tag)
|
||||
} else {
|
||||
fragmentTransaction.show(fragment)
|
||||
}
|
||||
|
||||
fragmentTransaction.setPrimaryNavigationFragment(fragment)
|
||||
fragmentTransaction.setReorderingAllowed(true)
|
||||
fragmentTransaction.commitNow()
|
||||
}
|
||||
|
||||
fun selectCan(model: CanResponse) {
|
||||
val intent = Intent(applicationContext, CanPaymentActivity::class.java)
|
||||
intent.putExtra(Constants.EXTRA_CAN, model)
|
||||
|
@ -123,9 +102,4 @@ class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>(
|
|||
|
||||
finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val IAP_TAG_KEY = "iap"
|
||||
const val PG_TAG_KEY = "pg"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package kr.co.vividnext.sodalive.mypage.can.charge.iap
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
|
@ -13,10 +14,12 @@ import com.android.billingclient.api.BillingClient
|
|||
import com.android.billingclient.api.BillingClientStateListener
|
||||
import com.android.billingclient.api.BillingFlowParams
|
||||
import com.android.billingclient.api.BillingResult
|
||||
import com.android.billingclient.api.ConsumeParams
|
||||
import com.android.billingclient.api.ProductDetails
|
||||
import com.android.billingclient.api.Purchase
|
||||
import com.android.billingclient.api.PurchasesUpdatedListener
|
||||
import com.android.billingclient.api.QueryProductDetailsParams
|
||||
import com.android.billingclient.api.QueryPurchasesParams
|
||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
|
@ -37,57 +40,10 @@ class CanChargeIapFragment : BaseFragment<FragmentCanChargeIapBinding>(
|
|||
private val handler = Handler(Looper.getMainLooper())
|
||||
private var selectedProductDetails: ProductDetails? = null
|
||||
|
||||
private val purchaseUpdateListener = PurchasesUpdatedListener { billingResult, purchases ->
|
||||
if (
|
||||
billingResult.responseCode == BillingClient.BillingResponseCode.OK &&
|
||||
purchases != null &&
|
||||
selectedProductDetails != null
|
||||
) {
|
||||
for (purchase in purchases) {
|
||||
handlePurchase(purchase)
|
||||
}
|
||||
} else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
|
||||
selectedProductDetails = null
|
||||
handler.post {
|
||||
Toast.makeText(requireActivity(), "구매를 취소했습니다.", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} else {
|
||||
selectedProductDetails = null
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
"구매를 하지 못했습니다.\n다시 시도해 주세요.",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}
|
||||
private lateinit var purchaseUpdateListener: PurchasesUpdatedListener
|
||||
|
||||
private fun handlePurchase(purchase: Purchase) {
|
||||
if (
|
||||
purchase.purchaseState == Purchase.PurchaseState.PURCHASED &&
|
||||
!purchase.isAcknowledged
|
||||
) {
|
||||
viewModel.chargeCan(
|
||||
title = selectedProductDetails!!.name,
|
||||
selectedProductDetails = selectedProductDetails!!,
|
||||
purchase = purchase
|
||||
) { chargeCan ->
|
||||
handler.post {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
"캔이 충전되었습니다",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
SharedPreferenceManager.can += chargeCan
|
||||
|
||||
val activity = requireActivity() as? CanChargeActivity
|
||||
if (activity != null) {
|
||||
activity.successIapCharge()
|
||||
} else {
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fun safeContext(): Context? {
|
||||
return if (isAdded) context else null
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
@ -100,6 +56,31 @@ class CanChargeIapFragment : BaseFragment<FragmentCanChargeIapBinding>(
|
|||
setupBillingClient()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
billingClient.startConnection(object : BillingClientStateListener {
|
||||
override fun onBillingServiceDisconnected() {
|
||||
viewModel.showToast("인 앱 결제 이용이 불가능 합니다. 다시 시도해 주세요.")
|
||||
viewModel.setLoading(false)
|
||||
}
|
||||
|
||||
override fun onBillingSetupFinished(billingResult: BillingResult) {
|
||||
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||
queryAndConsumeUnconsumedPurchases()
|
||||
} else {
|
||||
viewModel.showToast("인 앱 결제 이용이 불가능 합니다. 다시 시도해 주세요.")
|
||||
viewModel.setLoading(false)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
billingClient.endConnection()
|
||||
}
|
||||
|
||||
private fun bindData() {
|
||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||
if (it) {
|
||||
|
@ -162,39 +143,34 @@ class CanChargeIapFragment : BaseFragment<FragmentCanChargeIapBinding>(
|
|||
}
|
||||
|
||||
private fun setupBillingClient() {
|
||||
purchaseUpdateListener = PurchasesUpdatedListener { billingResult, purchases ->
|
||||
handler.post {
|
||||
if (
|
||||
billingResult.responseCode == BillingClient.BillingResponseCode.OK &&
|
||||
purchases != null &&
|
||||
selectedProductDetails != null
|
||||
) {
|
||||
for (purchase in purchases) {
|
||||
handlePurchase(purchase)
|
||||
}
|
||||
} else if (
|
||||
billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED
|
||||
) {
|
||||
selectedProductDetails = null
|
||||
viewModel.showToast("구매를 취소했습니다.")
|
||||
} else {
|
||||
selectedProductDetails = null
|
||||
viewModel.showToast("구매를 하지 못했습니다.\n다시 시도해 주세요.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
billingClient = BillingClient.newBuilder(requireActivity())
|
||||
.enablePendingPurchases()
|
||||
.setListener(purchaseUpdateListener)
|
||||
.build()
|
||||
|
||||
loadingDialog.show(screenWidth)
|
||||
billingClient.startConnection(object : BillingClientStateListener {
|
||||
override fun onBillingServiceDisconnected() {
|
||||
handler.post {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
"인 앱 결제 이용이 불가능 합니다. 다시 시도해 주세요.",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
|
||||
override fun onBillingSetupFinished(billingResult: BillingResult) {
|
||||
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||
queryAvailableCans()
|
||||
} else {
|
||||
handler.post {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
"인 앱 결제 이용이 불가능 합니다. 다시 시도해 주세요.",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
|
@ -224,16 +200,70 @@ class CanChargeIapFragment : BaseFragment<FragmentCanChargeIapBinding>(
|
|||
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||
handler.post { adapter.addItems(productDetailsList) }
|
||||
} else {
|
||||
handler.post {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
"인 앱 결제 이용이 불가능 합니다. 다시 시도해 주세요.",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
viewModel.showToast("인 앱 결제 이용이 불가능 합니다. 다시 시도해 주세요.")
|
||||
}
|
||||
|
||||
viewModel.setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
handler.post { loadingDialog.dismiss() }
|
||||
private fun queryAndConsumeUnconsumedPurchases() {
|
||||
val queryPurchaseParams = QueryPurchasesParams.newBuilder()
|
||||
.setProductType(BillingClient.ProductType.INAPP)
|
||||
.build()
|
||||
|
||||
billingClient.queryPurchasesAsync(
|
||||
queryPurchaseParams
|
||||
) { result, purchaseList ->
|
||||
if (result.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||
if (purchaseList.isNotEmpty()) {
|
||||
for (purchase in purchaseList) {
|
||||
if (!purchase.isAcknowledged) {
|
||||
consumePurchase(purchase)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
queryAvailableCans()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun consumePurchase(purchase: Purchase) {
|
||||
val params = ConsumeParams.newBuilder()
|
||||
.setPurchaseToken(purchase.purchaseToken)
|
||||
.build()
|
||||
|
||||
billingClient.consumeAsync(params) { billingResult, _ ->
|
||||
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||
queryAvailableCans()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePurchase(purchase: Purchase) {
|
||||
if (
|
||||
purchase.purchaseState == Purchase.PurchaseState.PURCHASED &&
|
||||
!purchase.isAcknowledged
|
||||
) {
|
||||
viewModel.chargeCan(
|
||||
title = selectedProductDetails!!.name,
|
||||
selectedProductDetails = selectedProductDetails!!,
|
||||
purchase = purchase
|
||||
) { chargeCan ->
|
||||
handler.post {
|
||||
viewModel.showToast("캔이 충전되었습니다")
|
||||
SharedPreferenceManager.can += chargeCan
|
||||
|
||||
if (activity != null) {
|
||||
if (activity as? CanChargeActivity != null) {
|
||||
(activity as CanChargeActivity).successIapCharge()
|
||||
} else {
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,4 +71,12 @@ class CanChargeIapViewModel(private val repository: CanRepository) : BaseViewMod
|
|||
_toastLiveData.value = "구매를 하지 못했습니다.\n고객센터로 문의해 주시기 바랍니다."
|
||||
}
|
||||
}
|
||||
|
||||
fun showToast(message: String) {
|
||||
_toastLiveData.value = message
|
||||
}
|
||||
|
||||
fun setLoading(isLoading: Boolean) {
|
||||
_isLoading.value = isLoading
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue