Google 播放计费服务超时
Google play billing service timeout
我昨天在我的应用程序中设置了 Google 播放应用程序内购买的结算,一切都按预期工作,我可以查询产品,select 他们并购买。
今天这已经改变了,它突然不起作用并返回这些错误消息:
W/BillingClient: Async task is taking too long, cancel it!
D/billingSetupError: Timeout communicating with service
返回的错误响应代码是-3。下面是我连接到服务和查询 sku 详细信息的代码(一切都在我的视图模型中,因为我使用的是完整的撰写应用程序,所以无法访问 activity 或我所在的片段)
@HiltViewModel
class StoreViewModel @Inject constructor(
private val billingClientBuilder: BillingClient.Builder
) : ViewModel(), StoreEvents, BillingClientStateListener, PurchasesUpdatedListener {
companion object {
const val TAG = "StoreViewModel"
}
private val _state = MutableStateFlow(StoreScreenState.default)
val state: StateFlow<StoreScreenState> = _state
private val _purchaseTokens = MutableStateFlow(emptyList<String?>())
val purchaseTokens: StateFlow<List<String?>> = _purchaseTokens
private val availableSkus = listOf(
"comic_pack",
"elements_pack"
)
private val BACKOFF_IN_MILLIS = 500
private var backoffAttempts = 0
private var billingClient = billingClientBuilder
.setListener(this)
.enablePendingPurchases()
.build()
init {
billingClient.startConnection(this)
viewModelScope.launch {
state.collect {
it.skuDetails.forEach {
Log.d(TAG, it.toString())
}
}
}
}
private suspend fun queryOneTimeProducts(): List<SkuDetails> = withContext(Dispatchers.IO) {
if (!billingClient.isReady) {
Log.e("TAG", "queryOneTimeProducts: BillingClient is not ready")
return@withContext emptyList()
}
val availableSkus = SkuDetailsParams
.newBuilder()
.setSkusList(availableSkus)
.setType(BillingClient.SkuType.INAPP)
.build()
return@withContext runCatching {
val result = billingClient.querySkuDetails(availableSkus)
result.skuDetailsList ?: emptyList()
}.getOrNull() ?: emptyList()
}
private suspend fun handlePurchase(purchase: Purchase) {
Log.d("purchaseComplete", purchase.toString())
val consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
withContext(Dispatchers.IO) {
billingClient.consumePurchase(consumeParams)
}
}
private fun updateLoading(isLoading: Boolean) {
_state.value = state.value.copy(
loading = isLoading
)
}
private fun updateProducts(products: List<SkuDetails>) {
_state.value = state.value.copy(
skuDetails = products
)
}
override fun StoreItemClicked(activity: Activity, name: String) {
val selectedSku = state.value.skuDetails.find { it.title == name }
val flowParams = selectedSku?.let {
it
BillingFlowParams.newBuilder()
.setSkuDetails(it)
.build()
}
flowParams?.let { billingClient.launchBillingFlow(activity, it) }
}
override fun onBillingServiceDisconnected() {
viewModelScope.launch {
if (backoffAttempts == 0) {
delay(BACKOFF_IN_MILLIS.toLong())
} else {
delay(backoffAttempts * BACKOFF_IN_MILLIS.toLong())
}
if (!billingClient.isReady) {
billingClient.startConnection(this@StoreViewModel)
backoffAttempts++
}
}
}
override fun onBillingSetupFinished(billingResult: BillingResult) {
backoffAttempts = 0
Log.d("responsecode", billingResult.responseCode.toString())
if (billingResult.responseCode != 0) {
if (billingResult.responseCode == 2 || billingResult.responseCode == 3) {
viewModelScope.launch {
Log.d("billingSetupError", billingResult.debugMessage)
}
} else {
viewModelScope.launch {
Log.d("billingSetupError", billingResult.debugMessage)
}
}
} else {
viewModelScope.launch {
val products = queryOneTimeProducts()
Log.d("PRODUCTS", products.toString())
updateProducts(products)
updateLoading(false)
}
}
}
override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList<Purchase>?) {
if (result.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
viewModelScope.launch {
Log.d("purchase", purchase.toString())
handlePurchase(purchase)
}
}
} else if (result.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
} else {
// Handle any other error codes.
}
}
}
我在使用v4.1.0的时候遇到了同样的问题。
我改用了 3.0.2 版,问题消失了。
这可能是一个临时解决方案,因为不建议使用以前的版本。
也许 3.0.2 和 4.1.0 之间的版本也可以修复它。
在此处的发行说明中 https://developer.android.com/google/play/billing/release-notes 没有找到与“超时问题”相关的任何内容。
我昨天在我的应用程序中设置了 Google 播放应用程序内购买的结算,一切都按预期工作,我可以查询产品,select 他们并购买。
今天这已经改变了,它突然不起作用并返回这些错误消息:
W/BillingClient: Async task is taking too long, cancel it!
D/billingSetupError: Timeout communicating with service
返回的错误响应代码是-3。下面是我连接到服务和查询 sku 详细信息的代码(一切都在我的视图模型中,因为我使用的是完整的撰写应用程序,所以无法访问 activity 或我所在的片段)
@HiltViewModel
class StoreViewModel @Inject constructor(
private val billingClientBuilder: BillingClient.Builder
) : ViewModel(), StoreEvents, BillingClientStateListener, PurchasesUpdatedListener {
companion object {
const val TAG = "StoreViewModel"
}
private val _state = MutableStateFlow(StoreScreenState.default)
val state: StateFlow<StoreScreenState> = _state
private val _purchaseTokens = MutableStateFlow(emptyList<String?>())
val purchaseTokens: StateFlow<List<String?>> = _purchaseTokens
private val availableSkus = listOf(
"comic_pack",
"elements_pack"
)
private val BACKOFF_IN_MILLIS = 500
private var backoffAttempts = 0
private var billingClient = billingClientBuilder
.setListener(this)
.enablePendingPurchases()
.build()
init {
billingClient.startConnection(this)
viewModelScope.launch {
state.collect {
it.skuDetails.forEach {
Log.d(TAG, it.toString())
}
}
}
}
private suspend fun queryOneTimeProducts(): List<SkuDetails> = withContext(Dispatchers.IO) {
if (!billingClient.isReady) {
Log.e("TAG", "queryOneTimeProducts: BillingClient is not ready")
return@withContext emptyList()
}
val availableSkus = SkuDetailsParams
.newBuilder()
.setSkusList(availableSkus)
.setType(BillingClient.SkuType.INAPP)
.build()
return@withContext runCatching {
val result = billingClient.querySkuDetails(availableSkus)
result.skuDetailsList ?: emptyList()
}.getOrNull() ?: emptyList()
}
private suspend fun handlePurchase(purchase: Purchase) {
Log.d("purchaseComplete", purchase.toString())
val consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
withContext(Dispatchers.IO) {
billingClient.consumePurchase(consumeParams)
}
}
private fun updateLoading(isLoading: Boolean) {
_state.value = state.value.copy(
loading = isLoading
)
}
private fun updateProducts(products: List<SkuDetails>) {
_state.value = state.value.copy(
skuDetails = products
)
}
override fun StoreItemClicked(activity: Activity, name: String) {
val selectedSku = state.value.skuDetails.find { it.title == name }
val flowParams = selectedSku?.let {
it
BillingFlowParams.newBuilder()
.setSkuDetails(it)
.build()
}
flowParams?.let { billingClient.launchBillingFlow(activity, it) }
}
override fun onBillingServiceDisconnected() {
viewModelScope.launch {
if (backoffAttempts == 0) {
delay(BACKOFF_IN_MILLIS.toLong())
} else {
delay(backoffAttempts * BACKOFF_IN_MILLIS.toLong())
}
if (!billingClient.isReady) {
billingClient.startConnection(this@StoreViewModel)
backoffAttempts++
}
}
}
override fun onBillingSetupFinished(billingResult: BillingResult) {
backoffAttempts = 0
Log.d("responsecode", billingResult.responseCode.toString())
if (billingResult.responseCode != 0) {
if (billingResult.responseCode == 2 || billingResult.responseCode == 3) {
viewModelScope.launch {
Log.d("billingSetupError", billingResult.debugMessage)
}
} else {
viewModelScope.launch {
Log.d("billingSetupError", billingResult.debugMessage)
}
}
} else {
viewModelScope.launch {
val products = queryOneTimeProducts()
Log.d("PRODUCTS", products.toString())
updateProducts(products)
updateLoading(false)
}
}
}
override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList<Purchase>?) {
if (result.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
viewModelScope.launch {
Log.d("purchase", purchase.toString())
handlePurchase(purchase)
}
}
} else if (result.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
} else {
// Handle any other error codes.
}
}
}
我在使用v4.1.0的时候遇到了同样的问题。 我改用了 3.0.2 版,问题消失了。 这可能是一个临时解决方案,因为不建议使用以前的版本。
也许 3.0.2 和 4.1.0 之间的版本也可以修复它。 在此处的发行说明中 https://developer.android.com/google/play/billing/release-notes 没有找到与“超时问题”相关的任何内容。