You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI安卓应用配置Google Play订阅遇阻:上传AAB仍提示传APK

MAUI安卓集成Google Play Billing后订阅页面仍提示需上传APK的问题排查

我正在尝试在MAUI安卓应用中集成Google Play Billing Library,实现订阅和优惠码功能。按相关指引,上传初始化了Billing Client的AAB包后,应该能在Play Console中解锁订阅设置,但上传完成后进入订阅配置页面仍提示需上传APK。以下是我在Android目录中使用的SubscriptionManager类代码,请问哪里操作有误?

using System.Collections.Generic;
using System.Linq;
using Android.App;
using Android.Content;
using Android.BillingClient.Api;

public class SubscriptionManager
{
    private BillingClient billingClient;
    private Context context;
    private Action<bool> subscriptionCallback;

    public SubscriptionManager(Context context)
    {
        this.context = context;
        InitializeBillingClient();
    }

    private void InitializeBillingClient()
    {
        billingClient = BillingClient.NewBuilder(context)
            .EnablePendingPurchases()
            .SetListener(new PurchasesUpdateListener(this))
            .Build();

        billingClient.StartConnection(new SubscriptionConnectionListener(this));
    }

    private class SubscriptionConnectionListener : Java.Lang.Object, IBillingClientStateListener
    {
        private readonly SubscriptionManager subscriptionManager;

        public SubscriptionConnectionListener(SubscriptionManager subscriptionManager)
        {
            this.subscriptionManager = subscriptionManager;
        }

        public void OnBillingServiceDisconnected()
        {
            // Try to restart the connection on the next request to BillingClient
            subscriptionManager.InitializeBillingClient();
        }

        public void OnBillingSetupFinished(BillingResult billingResult)
        {
            if (billingResult.ResponseCode == BillingResponseCode.Ok)
            {
                // BillingClient is ready
            }
            else
            {
                // Handle setup failure
                // Example: Log error or show a message to the user
            }
        }
    }

    public void InitiateSubscriptionPurchase(string skuId, Action<bool> callback)
    {
        subscriptionCallback = callback;
        SkuDetailsParams.Builder paramsBuilder = SkuDetailsParams.NewBuilder();
        paramsBuilder.SetType(BillingClient.SkuType.Subs);

        List<string> skuList = new List<string> { skuId };
        paramsBuilder.SetSkusList(skuList);

        SkuDetailsParams skuDetailsParams = paramsBuilder.Build();

        billingClient.QuerySkuDetailsAsync(skuDetailsParams);
    }

    private void LaunchSubscriptionBillingFlow(SkuDetails skuDetails)
    {
        BillingFlowParams billingFlowParams = BillingFlowParams.NewBuilder()
            .SetSkuDetails(skuDetails)
            .Build();
        BillingResult result = billingClient.LaunchBillingFlow((Activity)context, billingFlowParams);
        if (result.ResponseCode != BillingResponseCode.Ok)
        {
         
            subscriptionCallback?.Invoke(false);
        }
    }

    private class SkuDetailsResponseListener : Java.Lang.Object, ISkuDetailsResponseListener
    {
        private readonly SubscriptionManager subscriptionManager;

        public SkuDetailsResponseListener(SubscriptionManager subscriptionManager)
        {
            this.subscriptionManager = subscriptionManager;
        }

        public void OnSkuDetailsResponse(BillingResult billingResult, IList<SkuDetails> skuDetailsList)
        {
            if (billingResult.ResponseCode == BillingResponseCode.Ok && skuDetailsList != null && skuDetailsList.Count > 0)
            {
                SkuDetails skuDetails = skuDetailsList.FirstOrDefault(); 
                subscriptionManager.LaunchSubscriptionBillingFlow(skuDetails);
            }
            else
            {
               
                subscriptionManager.subscriptionCallback?.Invoke(false);
            }
        }
    }

    internal class PurchasesUpdateListener : Java.Lang.Object, IPurchasesUpdatedListener
    {
        private readonly SubscriptionManager subscriptionManager;

        public PurchasesUpdateListener(SubscriptionManager subscriptionManager)
        {
            this.subscriptionManager = subscriptionManager;
        }

        public void OnPurchasesUpdated(BillingResult billingResult, IList<Purchase> purchases)
        {
            if (billingResult.ResponseCode == BillingResponseCode.Ok && purchases != null)
            {
                foreach (var purchase in purchases)
                {
                    // Handle each purchase
                    if (purchase.PurchaseState == PurchaseState.Purchased)
                    {
                        // Purchase was successful
                        subscriptionManager.subscriptionCallback?.Invoke(true);
                    }
                    else if (purchase.PurchaseState == PurchaseState.Pending)
                    {
                        // Purchase is pending, handle accordingly
                        // Example: Show a message to the user
                    }
                    else
                    {
                        // Purchase failed or was canceled
                        subscriptionManager.subscriptionCallback?.Invoke(false);
                    }
                }
            }
            else
            {
                // Handle purchase update failure
                subscriptionManager.subscriptionCallback?.Invoke(false);
            }
        }
    }
}

问题排查与修复建议

  • 代码核心错误:InitiateSubscriptionPurchase方法中调用QuerySkuDetailsAsync时,没有传入SkuDetailsResponseListener实例,导致该API调用无实际执行逻辑,Play Console的检测机制无法识别到有效Billing集成。修复代码如下:
    billingClient.QuerySkuDetailsAsync(skuDetailsParams, new SkuDetailsResponseListener(this));
    
  • AAB包状态检查:确保上传的是正式签名的AAB,且已分配到开放测试/封闭测试/生产轨道,仅草稿状态的包无法触发订阅功能解锁。
  • Play Console基础配置:确认已完成应用内容分级、定价设置等必填项,未完成基础配置可能导致订阅页面无法解锁。
  • 依赖版本验证:检查项目中Google Play Billing Library的版本,建议使用最新稳定版,避免因版本兼容问题导致检测失败。

内容的提问来源于stack exchange,提问作者rmr84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:12:18