升级 Google 内购库
This commit is contained in:
@@ -18,8 +18,8 @@ import android.widget.TextView
|
|||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.android.billingclient.api.BillingClient
|
import com.android.billingclient.api.BillingClient
|
||||||
import com.android.billingclient.api.BillingResult
|
import com.android.billingclient.api.BillingResult
|
||||||
|
import com.android.billingclient.api.ProductDetails
|
||||||
import com.android.billingclient.api.Purchase
|
import com.android.billingclient.api.Purchase
|
||||||
import com.android.billingclient.api.SkuDetails
|
|
||||||
import com.appsflyer.AFInAppEventParameterName
|
import com.appsflyer.AFInAppEventParameterName
|
||||||
import com.appsflyer.AFInAppEventType
|
import com.appsflyer.AFInAppEventType
|
||||||
import com.appsflyer.AppsFlyerLib
|
import com.appsflyer.AppsFlyerLib
|
||||||
@@ -123,7 +123,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
ResUtil.getString(R.string.avroom_firstcharge_firstchargedialog_01).toast()
|
ResUtil.getString(R.string.avroom_firstcharge_firstchargedialog_01).toast()
|
||||||
} else if (channel.equals(Constants.GOOGLE)) {
|
} else if (channel.equals(Constants.GOOGLE)) {
|
||||||
goodsList?.get(position)?.let { charge ->
|
goodsList?.get(position)?.let { charge ->
|
||||||
buyProduct(charge.skuDetails)
|
buyProduct(charge.productDetails)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CommonWebViewActivity.start(
|
CommonWebViewActivity.start(
|
||||||
@@ -142,18 +142,23 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
FirstChargeReward.ONE -> {
|
FirstChargeReward.ONE -> {
|
||||||
spanSize = 6
|
spanSize = 6
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstChargeReward.TWO_LEFT -> {
|
FirstChargeReward.TWO_LEFT -> {
|
||||||
spanSize = 3
|
spanSize = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstChargeReward.TWO_RIGHT -> {
|
FirstChargeReward.TWO_RIGHT -> {
|
||||||
spanSize = 3
|
spanSize = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstChargeReward.THREE -> {
|
FirstChargeReward.THREE -> {
|
||||||
spanSize = 2
|
spanSize = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstChargeReward.TWO_LEFT_SMALL -> {
|
FirstChargeReward.TWO_LEFT_SMALL -> {
|
||||||
spanSize = 3
|
spanSize = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstChargeReward.TWO_RIGHT_SMALL -> {
|
FirstChargeReward.TWO_RIGHT_SMALL -> {
|
||||||
spanSize = 3
|
spanSize = 3
|
||||||
}
|
}
|
||||||
@@ -196,11 +201,13 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
binding.rbPlanC.visibility = View.GONE
|
binding.rbPlanC.visibility = View.GONE
|
||||||
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
|
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
|
||||||
}
|
}
|
||||||
|
|
||||||
2 -> {
|
2 -> {
|
||||||
binding.rbPlanC.visibility = View.GONE
|
binding.rbPlanC.visibility = View.GONE
|
||||||
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
|
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
|
||||||
binding.rbPlanB.text = "$${goodsList[1].chargeMoney}"
|
binding.rbPlanB.text = "$${goodsList[1].chargeMoney}"
|
||||||
}
|
}
|
||||||
|
|
||||||
3 -> {
|
3 -> {
|
||||||
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
|
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
|
||||||
binding.rbPlanB.text = "$${goodsList[1].chargeMoney}"
|
binding.rbPlanB.text = "$${goodsList[1].chargeMoney}"
|
||||||
@@ -227,20 +234,19 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
for (bean in goodsList) {
|
for (bean in goodsList) {
|
||||||
productKeys.add(bean.chargeProdId)
|
productKeys.add(bean.chargeProdId)
|
||||||
}
|
}
|
||||||
billingManager?.querySkuDetailsAsync(
|
billingManager?.querySkuDetailsAsync(productKeys) { billingResult: BillingResult, productDetails: MutableList<ProductDetails> ->
|
||||||
BillingClient.SkuType.INAPP, productKeys
|
|
||||||
) { billingResult: BillingResult, skuDetailsList: List<SkuDetails>? ->
|
|
||||||
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
|
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
|
||||||
Log.w(
|
Log.w(
|
||||||
TAG,
|
TAG,
|
||||||
"Unsuccessful query for type: " + BillingClient.SkuType.INAPP
|
"Unsuccessful query for type: " + BillingClient.ProductType.INAPP + ". Error code: " + billingResult.responseCode
|
||||||
+ ". Error code: " + billingResult.responseCode
|
|
||||||
)
|
)
|
||||||
} else if (skuDetailsList != null && skuDetailsList.isNotEmpty()) {
|
return@querySkuDetailsAsync
|
||||||
|
}
|
||||||
|
if (productDetails.isNotEmpty()) {
|
||||||
for (chargeBean in goodsList) {
|
for (chargeBean in goodsList) {
|
||||||
for (skuDetails in skuDetailsList) {
|
for (skuDetails in productDetails) {
|
||||||
if (skuDetails.sku == chargeBean.chargeProdId) {
|
if (skuDetails.productId == chargeBean.chargeProdId) {
|
||||||
chargeBean.skuDetails = skuDetails
|
chargeBean.productDetails = skuDetails
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,7 +264,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
) {
|
) {
|
||||||
PayModel.get().verifyOrder(
|
PayModel.get().verifyOrder(
|
||||||
purchase.accountIdentifiers!!.obfuscatedAccountId,
|
purchase.accountIdentifiers!!.obfuscatedAccountId,
|
||||||
purchase.skus[0],
|
purchase.products[0],
|
||||||
purchase.packageName,
|
purchase.packageName,
|
||||||
purchase.purchaseToken
|
purchase.purchaseToken
|
||||||
)
|
)
|
||||||
@@ -267,12 +273,12 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
{ token: String? ->
|
{ token: String? ->
|
||||||
//L.i("token=" + token);
|
//L.i("token=" + token);
|
||||||
billingManager?.consumeAsync(token)
|
billingManager?.consumeAsync(token)
|
||||||
var skuDetails: SkuDetails? = null
|
var skuDetails: ProductDetails? = null
|
||||||
val goodList = goodsList
|
val goodList = goodsList
|
||||||
if (goodList != null && goodList.isNotEmpty()) {
|
if (!goodList.isNullOrEmpty()) {
|
||||||
for (datum in goodList) {
|
for (datum in goodList) {
|
||||||
if (datum.chargeProdId == purchase.skus[0]) {
|
if (datum.chargeProdId == purchase.products[0]) {
|
||||||
skuDetails = datum.skuDetails
|
skuDetails = datum.productDetails
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,12 +288,12 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
HashMap()
|
HashMap()
|
||||||
eventValue[AFInAppEventParameterName.CONTENT_TYPE] = "Gold"
|
eventValue[AFInAppEventParameterName.CONTENT_TYPE] = "Gold"
|
||||||
eventValue[AFInAppEventParameterName.QUANTITY] = 1
|
eventValue[AFInAppEventParameterName.QUANTITY] = 1
|
||||||
eventValue[AFInAppEventParameterName.CONTENT_ID] = purchase.orderId
|
eventValue[AFInAppEventParameterName.CONTENT_ID] = purchase.orderId!!
|
||||||
eventValue[AFInAppEventParameterName.REVENUE] =
|
eventValue[AFInAppEventParameterName.REVENUE] =
|
||||||
skuDetails.priceAmountMicros / 1000000f
|
skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros!! / 1000000f
|
||||||
eventValue["Price"] = skuDetails.price
|
eventValue["Price"] = skuDetails.oneTimePurchaseOfferDetails?.formattedPrice!!
|
||||||
eventValue[AFInAppEventParameterName.CURRENCY] =
|
eventValue[AFInAppEventParameterName.CURRENCY] =
|
||||||
skuDetails.priceCurrencyCode
|
skuDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode!!
|
||||||
AppsFlyerLib.getInstance().logEvent(
|
AppsFlyerLib.getInstance().logEvent(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
AFInAppEventType.PURCHASE,
|
AFInAppEventType.PURCHASE,
|
||||||
@@ -315,10 +321,10 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
|
|
||||||
/*购买商品*/
|
/*购买商品*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
fun buyProduct(skuDetails: SkuDetails?) {
|
fun buyProduct(skuDetails: ProductDetails?) {
|
||||||
if (skuDetails != null) {
|
if (skuDetails != null) {
|
||||||
Log.d(TAG, "BuyProduct:" + skuDetails.sku)
|
Log.d(TAG, "BuyProduct:" + skuDetails.productId)
|
||||||
PayModel.get().placeOrder(skuDetails.sku)
|
PayModel.get().placeOrder(skuDetails.productId)
|
||||||
.compose(bindToLifecycle())
|
.compose(bindToLifecycle())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
{ recordId: PayRecordId ->
|
{ recordId: PayRecordId ->
|
||||||
@@ -372,6 +378,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
bean.itemType = FirstChargeReward.ONE
|
bean.itemType = FirstChargeReward.ONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
2 -> {
|
2 -> {
|
||||||
for (i in firstChargeRewardList.indices) {
|
for (i in firstChargeRewardList.indices) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -381,11 +388,13 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
3 -> {
|
3 -> {
|
||||||
for (bean in firstChargeRewardList) {
|
for (bean in firstChargeRewardList) {
|
||||||
bean.itemType = FirstChargeReward.THREE
|
bean.itemType = FirstChargeReward.THREE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
4 -> {
|
4 -> {
|
||||||
for (i in firstChargeRewardList.indices) {
|
for (i in firstChargeRewardList.indices) {
|
||||||
if ((i + 1) % 2 != 0) {
|
if ((i + 1) % 2 != 0) {
|
||||||
@@ -395,6 +404,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
if (firstChargeRewardList.size % 3 == 0) {
|
if (firstChargeRewardList.size % 3 == 0) {
|
||||||
for (bean in firstChargeRewardList) {
|
for (bean in firstChargeRewardList) {
|
||||||
|
@@ -3,28 +3,20 @@ package com.yizhuan.erban.ui.pay;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
|
||||||
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
|
||||||
import com.android.billingclient.api.BillingClient;
|
import com.android.billingclient.api.BillingClient;
|
||||||
import com.android.billingclient.api.BillingClient.BillingResponseCode;
|
import com.android.billingclient.api.BillingClient.BillingResponseCode;
|
||||||
import com.android.billingclient.api.BillingClient.SkuType;
|
|
||||||
import com.android.billingclient.api.BillingClientStateListener;
|
import com.android.billingclient.api.BillingClientStateListener;
|
||||||
import com.android.billingclient.api.BillingFlowParams;
|
import com.android.billingclient.api.BillingFlowParams;
|
||||||
import com.android.billingclient.api.BillingResult;
|
import com.android.billingclient.api.BillingResult;
|
||||||
import com.android.billingclient.api.ConsumeParams;
|
import com.android.billingclient.api.ConsumeParams;
|
||||||
import com.android.billingclient.api.ConsumeResponseListener;
|
import com.android.billingclient.api.ProductDetails;
|
||||||
|
import com.android.billingclient.api.ProductDetailsResponseListener;
|
||||||
import com.android.billingclient.api.Purchase;
|
import com.android.billingclient.api.Purchase;
|
||||||
import com.android.billingclient.api.Purchase.PurchasesResult;
|
|
||||||
import com.android.billingclient.api.PurchasesUpdatedListener;
|
import com.android.billingclient.api.PurchasesUpdatedListener;
|
||||||
import com.android.billingclient.api.SkuDetails;
|
import com.android.billingclient.api.QueryProductDetailsParams;
|
||||||
import com.android.billingclient.api.SkuDetailsParams;
|
import com.android.billingclient.api.QueryPurchasesParams;
|
||||||
import com.android.billingclient.api.SkuDetailsResponseListener;
|
|
||||||
import com.yizhuan.erban.event.ChargeEvent;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -109,25 +101,23 @@ public class BillingManager implements PurchasesUpdatedListener {
|
|||||||
|
|
||||||
/*请求商品库存*/
|
/*请求商品库存*/
|
||||||
public void onQueryPurchases() {
|
public void onQueryPurchases() {
|
||||||
Runnable queryToExecute = () -> {
|
Runnable queryToExecute = () ->
|
||||||
//系统当前时间
|
billingClient.queryPurchasesAsync(
|
||||||
long time = System.currentTimeMillis();
|
QueryPurchasesParams.newBuilder()
|
||||||
//请求内购商品
|
.setProductType(BillingClient.ProductType.INAPP)
|
||||||
PurchasesResult purchasesResult = billingClient.queryPurchases(SkuType.INAPP);
|
.build(), this::onQueryPurchasesFinished);
|
||||||
onQueryPurchasesFinished(purchasesResult);
|
|
||||||
};
|
|
||||||
executeServiceRequest(queryToExecute);
|
executeServiceRequest(queryToExecute);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*请求商品信息完成*/
|
/*请求商品信息完成*/
|
||||||
private void onQueryPurchasesFinished(PurchasesResult result) {
|
private void onQueryPurchasesFinished(BillingResult result, List<Purchase> list) {
|
||||||
if (billingClient == null || result.getResponseCode() != BillingResponseCode.OK) {
|
if (billingClient == null || result.getResponseCode() != BillingResponseCode.OK) {
|
||||||
Log.w(TAG, "billingClient is null or result code (" + result.getResponseCode()
|
Log.w(TAG, "billingClient is null or result code (" + result.getResponseCode()
|
||||||
+ ") was bad - quitting");
|
+ ") was bad - quitting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
purchaseList.clear();
|
purchaseList.clear();
|
||||||
onPurchasesUpdated(result.getBillingResult(), result.getPurchasesList());
|
onPurchasesUpdated(result, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*更新商品*/
|
/*更新商品*/
|
||||||
@@ -178,28 +168,46 @@ public class BillingManager implements PurchasesUpdatedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*查询内购商品详情*/
|
/*查询内购商品详情*/
|
||||||
public void querySkuDetailsAsync(@SkuType final String itemType, final List<String> skuList,
|
public void querySkuDetailsAsync(final List<String> productIdList,
|
||||||
final SkuDetailsResponseListener listener) {
|
final ProductDetailsResponseListener listener) {
|
||||||
Runnable queryRequest = () -> {
|
Runnable queryRequest = () -> {
|
||||||
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
ArrayList<QueryProductDetailsParams.Product> products = new ArrayList<>();
|
||||||
params.setSkusList(skuList)
|
for (String productId : productIdList) {
|
||||||
.setType(itemType);
|
products.add(QueryProductDetailsParams.Product.newBuilder()
|
||||||
billingClient.querySkuDetailsAsync(params.build(), listener);
|
.setProductId(productId)
|
||||||
|
.setProductType(BillingClient.ProductType.INAPP)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
QueryProductDetailsParams queryProductDetailsParams =
|
||||||
|
QueryProductDetailsParams.newBuilder()
|
||||||
|
.setProductList(products)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
billingClient.queryProductDetailsAsync(
|
||||||
|
queryProductDetailsParams,
|
||||||
|
listener
|
||||||
|
);
|
||||||
};
|
};
|
||||||
executeServiceRequest(queryRequest);
|
executeServiceRequest(queryRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*启动购买,订购流程*/
|
/*启动购买,订购流程*/
|
||||||
public void initiatePurchaseFlow(final SkuDetails skuDetails, String recordId) {
|
public void initiatePurchaseFlow(final ProductDetails productDetails, String recordId) {
|
||||||
Runnable purchaseFlowRequest = () -> {
|
Runnable purchaseFlowRequest = () -> {
|
||||||
|
BillingFlowParams.ProductDetailsParams p = BillingFlowParams.ProductDetailsParams.newBuilder()
|
||||||
|
.setProductDetails(productDetails)
|
||||||
|
.build();
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
jsonObject.put("p", skuDetails.getPrice());
|
ProductDetails.OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails = productDetails.getOneTimePurchaseOfferDetails();
|
||||||
jsonObject.put("a", skuDetails.getPriceAmountMicros() / 10000);
|
if (oneTimePurchaseOfferDetails != null) {
|
||||||
jsonObject.put("c", skuDetails.getPriceCurrencyCode());
|
jsonObject.put("p", oneTimePurchaseOfferDetails.getFormattedPrice());
|
||||||
|
jsonObject.put("a", oneTimePurchaseOfferDetails.getPriceAmountMicros() / 10000);
|
||||||
|
jsonObject.put("c", oneTimePurchaseOfferDetails.getPriceCurrencyCode());
|
||||||
|
}
|
||||||
BillingFlowParams purchaseParams = BillingFlowParams.newBuilder()
|
BillingFlowParams purchaseParams = BillingFlowParams.newBuilder()
|
||||||
.setObfuscatedAccountId(recordId)
|
.setObfuscatedAccountId(recordId)
|
||||||
.setObfuscatedProfileId(jsonObject.toJSONString())
|
.setObfuscatedProfileId(jsonObject.toJSONString())
|
||||||
.setSkuDetails(skuDetails)
|
.setProductDetailsParamsList(List.of(p))
|
||||||
.build();
|
.build();
|
||||||
BillingResult billingResult = billingClient.launchBillingFlow(mActivity, purchaseParams);
|
BillingResult billingResult = billingClient.launchBillingFlow(mActivity, purchaseParams);
|
||||||
Log.i(TAG, " initiatePurchaseFlow billingResult=" + billingResult.getResponseCode() + " " + billingResult.getDebugMessage());
|
Log.i(TAG, " initiatePurchaseFlow billingResult=" + billingResult.getResponseCode() + " " + billingResult.getDebugMessage());
|
||||||
@@ -218,18 +226,8 @@ public class BillingManager implements PurchasesUpdatedListener {
|
|||||||
|
|
||||||
final ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken).build();
|
final ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken).build();
|
||||||
|
|
||||||
final ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
|
executeServiceRequest(() -> billingClient.consumeAsync(consumeParams, (billingResult, s) ->
|
||||||
@Override
|
mBillingUpdatesListener.onConsumeFinished(purchaseToken, billingResult.getResponseCode())));
|
||||||
public void onConsumeResponse(@NonNull @NotNull BillingResult billingResult, @NonNull @NotNull String s) {
|
|
||||||
mBillingUpdatesListener.onConsumeFinished(purchaseToken, billingResult.getResponseCode());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
executeServiceRequest(() -> billingClient.consumeAsync(consumeParams, consumeResponseListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void acknowledgePurchase(AcknowledgePurchaseParams acknowledgePurchaseParams, AcknowledgePurchaseResponseListener Listener) {
|
|
||||||
billingClient.acknowledgePurchase(acknowledgePurchaseParams, Listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,8 +24,8 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.billingclient.api.BillingClient;
|
import com.android.billingclient.api.BillingClient;
|
||||||
|
import com.android.billingclient.api.ProductDetails;
|
||||||
import com.android.billingclient.api.Purchase;
|
import com.android.billingclient.api.Purchase;
|
||||||
import com.android.billingclient.api.SkuDetails;
|
|
||||||
import com.appsflyer.AFInAppEventParameterName;
|
import com.appsflyer.AFInAppEventParameterName;
|
||||||
import com.appsflyer.AFInAppEventType;
|
import com.appsflyer.AFInAppEventType;
|
||||||
import com.appsflyer.AppsFlyerLib;
|
import com.appsflyer.AppsFlyerLib;
|
||||||
@@ -186,19 +186,19 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
|
|||||||
productKeys.add(chargeBean.getChargeProdId());
|
productKeys.add(chargeBean.getChargeProdId());
|
||||||
}
|
}
|
||||||
mChargeAdapter.setNewData(chargeBeanList);
|
mChargeAdapter.setNewData(chargeBeanList);
|
||||||
billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, productKeys, (billingResult, skuDetailsList) -> {
|
billingManager.querySkuDetailsAsync(productKeys, (billingResult, productDetails) -> {
|
||||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||||
Log.w(TAG, "Unsuccessful query for type: " + BillingClient.SkuType.INAPP
|
Log.w(TAG, "Unsuccessful query for type: " + BillingClient.ProductType.INAPP
|
||||||
+ ". Error code: " + billingResult.getResponseCode());
|
+ ". Error code: " + billingResult.getResponseCode());
|
||||||
getDialogManager().dismissDialog();
|
getDialogManager().dismissDialog();
|
||||||
toast(getString(R.string.Recharge_failure));
|
toast(getString(R.string.Recharge_failure));
|
||||||
} else if (skuDetailsList != null && skuDetailsList.size() > 0) {
|
} else if (productDetails.size() > 0) {
|
||||||
getDialogManager().dismissDialog();
|
getDialogManager().dismissDialog();
|
||||||
List<ChargeBean> showChargeList = new ArrayList<>();
|
List<ChargeBean> showChargeList = new ArrayList<>();
|
||||||
for (ChargeBean chargeBean : chargeBeanList) {
|
for (ChargeBean chargeBean : chargeBeanList) {
|
||||||
for (SkuDetails skuDetails : skuDetailsList) {
|
for (ProductDetails product : productDetails) {
|
||||||
if (skuDetails.getSku().equals(chargeBean.getChargeProdId())) {
|
if (product.getProductId().equals(chargeBean.getChargeProdId())) {
|
||||||
chargeBean.setSkuDetails(skuDetails);
|
chargeBean.setProductDetails(product);
|
||||||
showChargeList.add(chargeBean);
|
showChargeList.add(chargeBean);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -221,30 +221,28 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
|
|||||||
purchase.getAccountIdentifiers() != null) {
|
purchase.getAccountIdentifiers() != null) {
|
||||||
PayModel.get().verifyOrder(
|
PayModel.get().verifyOrder(
|
||||||
purchase.getAccountIdentifiers().getObfuscatedAccountId(),
|
purchase.getAccountIdentifiers().getObfuscatedAccountId(),
|
||||||
purchase.getSkus().get(0),
|
purchase.getProducts().get(0),
|
||||||
purchase.getPackageName(),
|
purchase.getPackageName(),
|
||||||
purchase.getPurchaseToken())
|
purchase.getPurchaseToken())
|
||||||
.compose(bindToLifecycle())
|
.compose(bindToLifecycle())
|
||||||
.subscribe(
|
.subscribe(token -> {
|
||||||
token -> {
|
|
||||||
//L.i("token=" + token);
|
|
||||||
billingManager.consumeAsync(token);
|
billingManager.consumeAsync(token);
|
||||||
|
|
||||||
SkuDetails skuDetails = null;
|
ProductDetails productDetails = null;
|
||||||
for (ChargeBean datum : mChargeAdapter.getData()) {
|
for (ChargeBean datum : mChargeAdapter.getData()) {
|
||||||
if (datum.getChargeProdId().equals(purchase.getSkus().get(0))) {
|
if (datum.getChargeProdId().equals(purchase.getProducts().get(0))) {
|
||||||
skuDetails = datum.getSkuDetails();
|
productDetails = datum.getProductDetails();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skuDetails != null) {
|
if (productDetails != null) {
|
||||||
Map<String, Object> eventValue = new HashMap<>();
|
Map<String, Object> eventValue = new HashMap<>();
|
||||||
eventValue.put(AFInAppEventParameterName.CONTENT_TYPE, "Gold");
|
eventValue.put(AFInAppEventParameterName.CONTENT_TYPE, "Gold");
|
||||||
eventValue.put(AFInAppEventParameterName.QUANTITY, 1);
|
eventValue.put(AFInAppEventParameterName.QUANTITY, 1);
|
||||||
eventValue.put(AFInAppEventParameterName.CONTENT_ID, purchase.getOrderId());
|
eventValue.put(AFInAppEventParameterName.CONTENT_ID, purchase.getOrderId());
|
||||||
eventValue.put(AFInAppEventParameterName.REVENUE, skuDetails.getPriceAmountMicros() / 1000000f);
|
eventValue.put(AFInAppEventParameterName.REVENUE, productDetails.getOneTimePurchaseOfferDetails().getPriceAmountMicros() / 1000000f);
|
||||||
eventValue.put("Price", skuDetails.getPrice());
|
eventValue.put("Price", productDetails.getOneTimePurchaseOfferDetails().getFormattedPrice());
|
||||||
eventValue.put(AFInAppEventParameterName.CURRENCY, skuDetails.getPriceCurrencyCode());
|
eventValue.put(AFInAppEventParameterName.CURRENCY, productDetails.getOneTimePurchaseOfferDetails().getPriceCurrencyCode());
|
||||||
AppsFlyerLib.getInstance().logEvent(getApplicationContext(), AFInAppEventType.PURCHASE, eventValue);
|
AppsFlyerLib.getInstance().logEvent(getApplicationContext(), AFInAppEventType.PURCHASE, eventValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -269,12 +267,12 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
|
|||||||
|
|
||||||
/*购买商品*/
|
/*购买商品*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
public void buyProduct(SkuDetails skuDetails) {
|
public void buyProduct(ProductDetails productDetails) {
|
||||||
if (skuDetails != null) {
|
if (productDetails != null) {
|
||||||
Log.d(TAG, "BuyProduct:" + skuDetails.getSku());
|
Log.d(TAG, "BuyProduct:" + productDetails.getProductId());
|
||||||
PayModel.get().placeOrder(skuDetails.getSku())
|
PayModel.get().placeOrder(productDetails.getProductId())
|
||||||
.compose(bindToLifecycle())
|
.compose(bindToLifecycle())
|
||||||
.subscribe(recordId -> billingManager.initiatePurchaseFlow(skuDetails, recordId.getRecordId()),
|
.subscribe(recordId -> billingManager.initiatePurchaseFlow(productDetails, recordId.getRecordId()),
|
||||||
throwable -> {
|
throwable -> {
|
||||||
if (throwable instanceof FailReasonException) {
|
if (throwable instanceof FailReasonException) {
|
||||||
FailReasonException failReasonException = (FailReasonException) throwable;
|
FailReasonException failReasonException = (FailReasonException) throwable;
|
||||||
@@ -342,8 +340,8 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
|
|||||||
}
|
}
|
||||||
if (mChargePosition != -1) {
|
if (mChargePosition != -1) {
|
||||||
ChargeBean bean = mChargeAdapter.getItem(mChargePosition);
|
ChargeBean bean = mChargeAdapter.getItem(mChargePosition);
|
||||||
if (bean != null && bean.getSkuDetails() != null) {
|
if (bean != null && bean.getProductDetails() != null) {
|
||||||
buyProduct(bean.getSkuDetails());
|
buyProduct(bean.getProductDetails());
|
||||||
//点击充值
|
//点击充值
|
||||||
HashMap<String, Object> map = new HashMap<>(3);
|
HashMap<String, Object> map = new HashMap<>(3);
|
||||||
map.put(IReportConstants.MONEY, bean.money);
|
map.put(IReportConstants.MONEY, bean.money);
|
||||||
|
@@ -21,8 +21,8 @@ public class ChargeAdapter extends BaseQuickAdapter<ChargeBean, BaseViewHolder>
|
|||||||
if (chargeBean == null) return;
|
if (chargeBean == null) return;
|
||||||
baseViewHolder.getView(R.id.ll_bg).setSelected(chargeBean.isSelected);
|
baseViewHolder.getView(R.id.ll_bg).setSelected(chargeBean.isSelected);
|
||||||
baseViewHolder.setText(R.id.tv_title, chargeBean.getProdName());
|
baseViewHolder.setText(R.id.tv_title, chargeBean.getProdName());
|
||||||
if (chargeBean.getSkuDetails() != null) {
|
if (chargeBean.getProductDetails() != null) {
|
||||||
baseViewHolder.setText(R.id.item_charge_money, chargeBean.getSkuDetails().getPrice());
|
baseViewHolder.setText(R.id.item_charge_money, chargeBean.getProductDetails().getOneTimePurchaseOfferDetails().getFormattedPrice());
|
||||||
} else {
|
} else {
|
||||||
baseViewHolder.setText(R.id.item_charge_money, "USD$" + chargeBean.getMoney());
|
baseViewHolder.setText(R.id.item_charge_money, "USD$" + chargeBean.getMoney());
|
||||||
}
|
}
|
||||||
|
@@ -14,8 +14,8 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.android.billingclient.api.BillingClient
|
import com.android.billingclient.api.BillingClient
|
||||||
import com.android.billingclient.api.BillingResult
|
import com.android.billingclient.api.BillingResult
|
||||||
|
import com.android.billingclient.api.ProductDetails
|
||||||
import com.android.billingclient.api.Purchase
|
import com.android.billingclient.api.Purchase
|
||||||
import com.android.billingclient.api.SkuDetails
|
|
||||||
import com.appsflyer.AFInAppEventParameterName
|
import com.appsflyer.AFInAppEventParameterName
|
||||||
import com.appsflyer.AFInAppEventType
|
import com.appsflyer.AFInAppEventType
|
||||||
import com.appsflyer.AppsFlyerLib
|
import com.appsflyer.AppsFlyerLib
|
||||||
@@ -233,12 +233,12 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
|||||||
|
|
||||||
binding.tvOpenVip.setOnClickListener {
|
binding.tvOpenVip.setOnClickListener {
|
||||||
if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
|
if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
|
||||||
if ((googleChargeBean?.skuDetails?.price ?: "0") == "0") {
|
if ((googleChargeBean?.productDetails?.oneTimePurchaseOfferDetails?.priceAmountMicros ?: "0") == "0") {
|
||||||
toast(getString(R.string.Recharge_failure))
|
toast(getString(R.string.Recharge_failure))
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
SelectPayTypeDialog.newInstance(
|
SelectPayTypeDialog.newInstance(
|
||||||
googleChargeBean?.skuDetails?.price ?: "0",
|
googleChargeBean?.productDetails?.oneTimePurchaseOfferDetails?.formattedPrice ?: "0",
|
||||||
true,
|
true,
|
||||||
googleChargeBean?.getMoney() ?: 0.0
|
googleChargeBean?.getMoney() ?: 0.0
|
||||||
)
|
)
|
||||||
@@ -248,7 +248,7 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
|||||||
}
|
}
|
||||||
setOnGoogleChargeClick {
|
setOnGoogleChargeClick {
|
||||||
googleChargeBean?.let { charge ->
|
googleChargeBean?.let { charge ->
|
||||||
buyProduct(charge.skuDetails)
|
buyProduct(charge.productDetails)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOnChargeClick {
|
setOnChargeClick {
|
||||||
@@ -396,20 +396,18 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
|||||||
chargeInfo?.let { chargeBean ->
|
chargeInfo?.let { chargeBean ->
|
||||||
val productKeys: MutableList<String> = ArrayList()
|
val productKeys: MutableList<String> = ArrayList()
|
||||||
productKeys.add(chargeBean.getChargeProdId())
|
productKeys.add(chargeBean.getChargeProdId())
|
||||||
billingManager?.querySkuDetailsAsync(
|
billingManager?.querySkuDetailsAsync(productKeys) { billingResult: BillingResult, productDetails: List<ProductDetails> ->
|
||||||
BillingClient.SkuType.INAPP, productKeys
|
|
||||||
) { billingResult: BillingResult, skuDetailsList: List<SkuDetails>? ->
|
|
||||||
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
|
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
|
||||||
Log.w(
|
Log.w(
|
||||||
TAG,
|
TAG,
|
||||||
"Unsuccessful query for type: " + BillingClient.SkuType.INAPP
|
"Unsuccessful query for type: " + BillingClient.SkuType.INAPP
|
||||||
+ ". Error code: " + billingResult.responseCode
|
+ ". Error code: " + billingResult.responseCode
|
||||||
)
|
)
|
||||||
} else if (skuDetailsList != null && skuDetailsList.isNotEmpty()) {
|
} else if (productDetails.isNotEmpty()) {
|
||||||
val showChargeList: MutableList<ChargeBean> = ArrayList()
|
val showChargeList: MutableList<ChargeBean> = ArrayList()
|
||||||
for (skuDetails in skuDetailsList) {
|
for (skuDetails in productDetails) {
|
||||||
if (skuDetails.sku == chargeBean.getChargeProdId()) {
|
if (skuDetails.productId == chargeBean.getChargeProdId()) {
|
||||||
chargeBean.skuDetails = skuDetails
|
chargeBean.productDetails = skuDetails
|
||||||
showChargeList.add(chargeBean)
|
showChargeList.add(chargeBean)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -439,7 +437,7 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
|||||||
) {
|
) {
|
||||||
PayModel.get().verifyOrder(
|
PayModel.get().verifyOrder(
|
||||||
purchase.accountIdentifiers!!.obfuscatedAccountId,
|
purchase.accountIdentifiers!!.obfuscatedAccountId,
|
||||||
purchase.skus[0],
|
purchase.products[0],
|
||||||
purchase.packageName,
|
purchase.packageName,
|
||||||
purchase.purchaseToken
|
purchase.purchaseToken
|
||||||
)
|
)
|
||||||
@@ -448,21 +446,21 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
|||||||
{ token: String? ->
|
{ token: String? ->
|
||||||
//L.i("token=" + token);
|
//L.i("token=" + token);
|
||||||
billingManager?.consumeAsync(token)
|
billingManager?.consumeAsync(token)
|
||||||
var skuDetails: SkuDetails? = null
|
var skuDetails: ProductDetails? = null
|
||||||
if (googleChargeBean?.getChargeProdId() == purchase.skus[0]) {
|
if (googleChargeBean?.getChargeProdId() == purchase.products[0]) {
|
||||||
skuDetails = googleChargeBean?.skuDetails
|
skuDetails = googleChargeBean?.productDetails
|
||||||
}
|
}
|
||||||
if (skuDetails != null) {
|
if (skuDetails != null) {
|
||||||
val eventValue: MutableMap<String, Any> =
|
val eventValue: MutableMap<String, Any> =
|
||||||
HashMap()
|
HashMap()
|
||||||
eventValue[AFInAppEventParameterName.CONTENT_TYPE] = "Gold"
|
eventValue[AFInAppEventParameterName.CONTENT_TYPE] = "Gold"
|
||||||
eventValue[AFInAppEventParameterName.QUANTITY] = 1
|
eventValue[AFInAppEventParameterName.QUANTITY] = 1
|
||||||
eventValue[AFInAppEventParameterName.CONTENT_ID] = purchase.orderId
|
eventValue[AFInAppEventParameterName.CONTENT_ID] = purchase.orderId!!
|
||||||
eventValue[AFInAppEventParameterName.REVENUE] =
|
eventValue[AFInAppEventParameterName.REVENUE] =
|
||||||
skuDetails.priceAmountMicros / 1000000f
|
skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros!! / 1000000f
|
||||||
eventValue["Price"] = skuDetails.price
|
eventValue["Price"] = skuDetails.oneTimePurchaseOfferDetails?.formattedPrice!!
|
||||||
eventValue[AFInAppEventParameterName.CURRENCY] =
|
eventValue[AFInAppEventParameterName.CURRENCY] =
|
||||||
skuDetails.priceCurrencyCode
|
skuDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode!!
|
||||||
AppsFlyerLib.getInstance().logEvent(
|
AppsFlyerLib.getInstance().logEvent(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
AFInAppEventType.PURCHASE,
|
AFInAppEventType.PURCHASE,
|
||||||
@@ -490,15 +488,15 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
|||||||
|
|
||||||
/*购买商品*/
|
/*购买商品*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
fun buyProduct(skuDetails: SkuDetails?) {
|
fun buyProduct(productDetails: ProductDetails?) {
|
||||||
if (skuDetails != null) {
|
if (productDetails != null) {
|
||||||
Log.d(TAG, "BuyProduct:" + skuDetails.sku)
|
Log.d(TAG, "BuyProduct:" + productDetails.productId)
|
||||||
PayModel.get().placeOrder(skuDetails.sku)
|
PayModel.get().placeOrder(productDetails.productId)
|
||||||
.compose(bindToLifecycle())
|
.compose(bindToLifecycle())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
{ recordId: PayRecordId ->
|
{ recordId: PayRecordId ->
|
||||||
billingManager?.initiatePurchaseFlow(
|
billingManager?.initiatePurchaseFlow(
|
||||||
skuDetails,
|
productDetails,
|
||||||
recordId.recordId
|
recordId.recordId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -95,8 +95,8 @@ dependencies {
|
|||||||
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
|
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
|
||||||
|
|
||||||
//googleplay内购
|
//googleplay内购
|
||||||
api 'com.google.android.gms:play-services-wallet:19.1.0'
|
api 'com.google.android.gms:play-services-wallet:19.2.1'
|
||||||
api 'com.android.billingclient:billing:4.1.0'
|
api 'com.android.billingclient:billing:6.0.1'
|
||||||
|
|
||||||
api 'org.jetbrains.kotlin:kotlin-reflect:1.7.10'
|
api 'org.jetbrains.kotlin:kotlin-reflect:1.7.10'
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package com.yizhuan.xchat_android_core.pay.bean;
|
package com.yizhuan.xchat_android_core.pay.bean;
|
||||||
|
|
||||||
import com.android.billingclient.api.SkuDetails;
|
import com.android.billingclient.api.ProductDetails;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ public class ChargeBean implements Serializable{
|
|||||||
public int giftGoldNum;
|
public int giftGoldNum;
|
||||||
public int channel;
|
public int channel;
|
||||||
public String prodDesc;
|
public String prodDesc;
|
||||||
private SkuDetails skuDetails;
|
private ProductDetails mProductDetails;
|
||||||
|
|
||||||
public boolean isSelected;
|
public boolean isSelected;
|
||||||
|
|
||||||
@@ -82,12 +82,12 @@ public class ChargeBean implements Serializable{
|
|||||||
this.prodDesc = prodDesc;
|
this.prodDesc = prodDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkuDetails getSkuDetails() {
|
public ProductDetails getProductDetails() {
|
||||||
return skuDetails;
|
return mProductDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSkuDetails(SkuDetails skuDetails) {
|
public void setProductDetails(ProductDetails productDetails) {
|
||||||
this.skuDetails = skuDetails;
|
this.mProductDetails = productDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSelected() {
|
public boolean isSelected() {
|
||||||
@@ -107,7 +107,7 @@ public class ChargeBean implements Serializable{
|
|||||||
", giftGoldNum=" + giftGoldNum +
|
", giftGoldNum=" + giftGoldNum +
|
||||||
", channel=" + channel +
|
", channel=" + channel +
|
||||||
", prodDesc='" + prodDesc + '\'' +
|
", prodDesc='" + prodDesc + '\'' +
|
||||||
", skuDetails=" + skuDetails +
|
", productDetails=" + mProductDetails +
|
||||||
", isSelected=" + isSelected +
|
", isSelected=" + isSelected +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package com.yizhuan.xchat_android_core.pay.bean;
|
package com.yizhuan.xchat_android_core.pay.bean;
|
||||||
|
|
||||||
import com.android.billingclient.api.SkuDetails;
|
import com.android.billingclient.api.ProductDetails;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -17,5 +17,5 @@ public class FirstChargeGoods {
|
|||||||
private ArrayList<FirstChargeReward> firstChargeRewardList;
|
private ArrayList<FirstChargeReward> firstChargeRewardList;
|
||||||
private String giveMoney;
|
private String giveMoney;
|
||||||
private boolean finishCharge;
|
private boolean finishCharge;
|
||||||
private SkuDetails skuDetails;
|
private ProductDetails productDetails;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user