Skip to content

Commit

Permalink
Fixed consumable product purchase on Android (#420)
Browse files Browse the repository at this point in the history
For consumable items field "subscriptionOfferDetails" is always null
therefore null pointer exception is always thrown in this method

---------

Co-authored-by: artem.semenov <[email protected]>
  • Loading branch information
33-Elephants and artem.semenov authored Jun 22, 2023
1 parent dd841c4 commit dafaa92
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -507,19 +507,22 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler,

// Get the selected offerToken from the product, or first one if this is a migrated from 4.0 product
// or if the offerTokenIndex was not provided
val productDetailsParamsBuilder = ProductDetailsParams.newBuilder().setProductDetails(selectedProductDetails)
var offerToken : String? = null
if (offerTokenIndex != null) {
offerToken = selectedProductDetails.subscriptionOfferDetails?.get(offerTokenIndex)?.offerToken
}
if (offerToken == null) {
offerToken = selectedProductDetails.subscriptionOfferDetails!![0].offerToken

if (type == BillingClient.ProductType.SUBS) {
if (offerTokenIndex != null) {
offerToken = selectedProductDetails.subscriptionOfferDetails?.get(offerTokenIndex)?.offerToken
}
if (offerToken == null) {
offerToken = selectedProductDetails.subscriptionOfferDetails!![0].offerToken
}

productDetailsParamsBuilder.setOfferToken(offerToken)
}

val productDetailsParamsList =
listOf(ProductDetailsParams.newBuilder()
.setProductDetails(selectedProductDetails)
.setOfferToken(offerToken)
.build())
val productDetailsParamsList = listOf(productDetailsParamsBuilder.build())

builder.setProductDetailsParamsList(productDetailsParamsList)

val params = SubscriptionUpdateParams.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.dooboolab.flutterinapppurchase

import android.os.Handler
import io.flutter.plugin.common.MethodChannel
import java.lang.Runnable
import android.os.Looper

// MethodChannel.Result wrapper that responds on the platform thread.
Expand All @@ -11,16 +10,29 @@ class MethodResultWrapper internal constructor(
private val safeChannel: MethodChannel
) : MethodChannel.Result {
private val handler: Handler = Handler(Looper.getMainLooper())
private var exhausted: Boolean = false
override fun success(result: Any?) {
handler.post { safeResult.success(result) }
if (!exhausted) {
exhausted = true

handler.post { safeResult.success(result) }
}
}

override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
handler.post { safeResult.error(errorCode, errorMessage, errorDetails) }
if (!exhausted) {
exhausted = true

handler.post { safeResult.error(errorCode, errorMessage, errorDetails) }
}
}

override fun notImplemented() {
handler.post { safeResult.notImplemented() }
if (!exhausted) {
exhausted = true

handler.post { safeResult.notImplemented() }
}
}

fun invokeMethod(method: String?, arguments: Any?) {
Expand Down

0 comments on commit dafaa92

Please sign in to comment.