Android 使用播放计费库检查订阅状态

Android 使用播放计费库检查订阅状态,android,Android,在我的应用程序中,我有订阅。我使用IInapplingService实现了一个购买流,并使用经典方式检查订阅状态。我用这种方法遇到了一些问题。约1%的用户抱怨,在成功购买订阅后,这些订阅在应用程序中不起作用。我请求谷歌Pla支持这个问题。他们建议使用一个新的播放计费库。我看了说明书中的例子。但是,此示例不考虑检查订阅的状态。 我在页面上还发现:“Google Play服务返回登录到设备的用户帐户所做的购买。如果请求成功,Play Billing Library将查询结果存储在购买对象列表中。要检

在我的应用程序中,我有订阅。我使用IInapplingService实现了一个购买流,并使用经典方式检查订阅状态。我用这种方法遇到了一些问题。约1%的用户抱怨,在成功购买订阅后,这些订阅在应用程序中不起作用。我请求谷歌Pla支持这个问题。他们建议使用一个新的播放计费库。我看了说明书中的例子。但是,此示例不考虑检查订阅的状态。 我在页面上还发现:“Google Play服务返回登录到设备的用户帐户所做的购买。如果请求成功,Play Billing Library将查询结果存储在购买对象列表中。要检索列表,请调用PurchasesResult对象上的getPurchasesList()方法。”

因此,在教程中的BillingManager类中,我添加了一个代码,用于检查订阅的购买情况:

public Purchase.PurchasesResult querySubscriptionPurchases() {
        return mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
    }
在主活动中使用BillingManager:

mBillingManager = new BillingManager(this);
        Purchase.PurchasesResult purchasesResult = mBillingManager.querySubscriptionPurchases();
        if (purchasesResult != null) {
            List<Purchase> p = purchasesResult.getPurchasesList();
        }
mUpdateListener = new myBillingUpdateListener();
        mBillingManager = new BillingManager(this, getUpdateListener());
mBillingManager=new BillingManager(此);
PurchasesResult PurchasesResult=mBillingManager.querySubscriptionPurchases();
if(purchasesResult!=null){
List p=purchasesResult.getPurchasesList();
}
当我运行应用程序时,在logcat中我看到“I/BillingManager:onBillingSetupFinished()响应:0”。那么连接成功了吗

但是purchasesResult为null,我无法获取采购列表,以了解此列表包含的内容,从而获取活动订阅的SKU。在调试模式下,使用IInapplingService的经典方式成功返回购买,我有一个用于测试的活动订阅,它可以正常工作

BillingManager的完整列表:

public class BillingManager implements PurchasesUpdatedListener {
    private static final String TAG = "BillingManager";

    private final BillingClient mBillingClient;
    private final Activity mActivity;

    private static final HashMap<String, List<String>> SKUS;
    static
    {
        SKUS = new HashMap<>();
        SKUS.put(BillingClient.SkuType.SUBS, Arrays.asList("no_ads", "sub2", "sub3"));
    }

    public BillingManager(Activity activity) {
        mActivity = activity;
        mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
        mBillingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponse) {
                if (billingResponse == BillingClient.BillingResponse.OK) {
                    Log.i(TAG, "onBillingSetupFinished() response: " + billingResponse);
                } else {
                    Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
                }
            }
            @Override
            public void onBillingServiceDisconnected() {
                Log.w(TAG, "onBillingServiceDisconnected()");
            }
        });
    }

    @Override
    public void onPurchasesUpdated(@BillingClient.BillingResponse int responseCode,
                                   List<Purchase> purchases) {
        Log.d(TAG, "onPurchasesUpdated() response: " + responseCode);
    }

    public List<String> getSkus(@BillingClient.SkuType String type) {
        return SKUS.get(type);
    }

    private void startServiceConnectionIfNeeded(final Runnable executeOnSuccess) {
        if (mBillingClient.isReady()) {
            if (executeOnSuccess != null) {
                executeOnSuccess.run();
            }
        } else {
            mBillingClient.startConnection(new BillingClientStateListener() {
                @Override
                public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponse) {
                    if (billingResponse == BillingClient.BillingResponse.OK) {
                        Log.i(TAG, "onBillingSetupFinished() response: " + billingResponse);
                        if (executeOnSuccess != null) {
                            executeOnSuccess.run();
                        }
                    } else {
                        Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
                    }
                }

                @Override
                public void onBillingServiceDisconnected() {
                    Log.w(TAG, "onBillingServiceDisconnected()");
                }
            });
        }
    }

    public Purchase.PurchasesResult querySubscriptionPurchases() {
        return mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
    }

    public void querySkuDetailsAsync(@BillingClient.SkuType final String itemType,
                                     final List<String> skuList, final SkuDetailsResponseListener listener) {
        // Specify a runnable to start when connection to Billing client is established
        Runnable executeOnConnectedService = new Runnable() {
            @Override
            public void run() {
                SkuDetailsParams skuDetailsParams = SkuDetailsParams.newBuilder()
                        .setSkusList(skuList).setType(itemType).build();
                mBillingClient.querySkuDetailsAsync(skuDetailsParams,
                        new SkuDetailsResponseListener() {
                            @Override
                            public void onSkuDetailsResponse(int responseCode,
                                                             List<SkuDetails> skuDetailsList) {
                                listener.onSkuDetailsResponse(responseCode, skuDetailsList);
                            }
                        });
            }
        };

        // If Billing client was disconnected, we retry 1 time and if success, execute the query
        startServiceConnectionIfNeeded(executeOnConnectedService);
    }

    public void startPurchaseFlow(final String skuId, final String billingType) {
        // Specify a runnable to start when connection to Billing client is established
        Runnable executeOnConnectedService = new Runnable() {
            @Override
            public void run() {
                BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                        .setType(billingType)
                        .setSku(skuId)
                        .build();
                mBillingClient.launchBillingFlow(mActivity, billingFlowParams);
            }
        };

        // If Billing client was disconnected, we retry 1 time and if success, execute the query
        startServiceConnectionIfNeeded(executeOnConnectedService);
    }

    public void destroy() {
        mBillingClient.endConnection();
    }
}
@Override
    public void onPurchasesUpdated(int resultCode, List<Purchase> purchases) {
        if (resultCode == BillingClient.BillingResponse.OK) {
            for (Purchase purchase : purchases) {
                handlePurchase(purchase);
            }
            mBillingUpdatesListener.onPurchasesUpdated(mPurchases);
        } else if (resultCode == BillingClient.BillingResponse.USER_CANCELED) {
            Log.i(TAG, "onPurchasesUpdated() - user cancelled the purchase flow - skipping");
        } else {
            Log.w(TAG, "onPurchasesUpdated() got unknown resultCode: " + resultCode);
        }
    }
公共类BillingManager实现PurchasesUpdatedListener{
私有静态最终字符串标记=“BillingManager”;
私人最终计费客户mBillingClient;
私人最终活动能力;
私有静态最终哈希映射SKU;
静止的
{
SKUS=新的HashMap();
SKU.put(BillingClient.SkuType.SUBS,Arrays.asList(“无广告”、“sub2”、“sub3”));
}
公共计费经理(活动){
活动性=活动性;
mBillingClient=BillingClient.newBuilder(mActivity).setListener(this.build();
mBillingClient.startConnection(新的BillingClientStateListener(){
@凌驾
已完成BillingSetupFinished(@BillingClient.BillingResponse int BillingResponse)上的公共无效{
if(billingResponse==BillingClient.billingResponse.OK){
Log.i(标记“onBillingSetupFinished()响应:”+billingResponse);
}否则{
w(标记“onBillingSetupFinished()错误代码:”+billingResponse);
}
}
@凌驾
公共无效onBillingServiceDisconnected(){
w(标记“onBillingServiceDisconnected()”);
}
});
}
@凌驾
PurchaseSupdated(@BillingClient.BillingResponse int responseCode)上的公共无效,
(列出购买清单){
Log.d(标记“onPurchasesUpdated()响应:”+responseCode);
}
公共列表getSKU(@BillingClient.SkuType字符串类型){
返回SKU.get(类型);
}
private void StartServiceConnectionInneed(最终可运行ExecuteonSucture){
if(mBillingClient.isReady()){
if(executeOnSuccess!=null){
executeOnSuccess.run();
}
}否则{
mBillingClient.startConnection(新的BillingClientStateListener(){
@凌驾
已完成BillingSetupFinished(@BillingClient.BillingResponse int BillingResponse)上的公共无效{
if(billingResponse==BillingClient.billingResponse.OK){
Log.i(标记“onBillingSetupFinished()响应:”+billingResponse);
if(executeOnSuccess!=null){
executeOnSuccess.run();
}
}否则{
w(标记“onBillingSetupFinished()错误代码:”+billingResponse);
}
}
@凌驾
公共无效onBillingServiceDisconnected(){
w(标记“onBillingServiceDisconnected()”);
}
});
}
}
public Purchase.purchases结果querySubscriptionPurchases(){
返回mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
}
public void queryskudailsasync(@BillingClient.SkuType final String itemType,
最终列表skuList、最终SkuDetailsResponseListener侦听器){
//指定在建立到计费客户端的连接时启动的runnable
Runnable executeOnConnectedService=new Runnable(){
@凌驾
公开募捐{
SkuDetailsParams SkuDetailsParams=SkuDetailsParams.newBuilder()
.setskulist(skuList).setType(itemType).build();
mBillingClient.queryskuedetailsasync(skuedetailsparams,
新SkuDetailsResponseListener(){
@凌驾
公共无效的详细信息响应(int响应代码,
列表(详细信息列表){
onSkuDetailsResponse(responseCode,skuDetailsList);
}
});
}
};
//如果计费客户端已断开连接,我们将重试1次,如果成功,则执行查询
StartServiceConnectionInneed(executeOnConnectedService);
}
public void startPurchaseFlow(最终字符串skuId,最终字符串billingType){
//指定一个runnable以在连接t时启动
@Override
    public void onPurchasesUpdated(int resultCode, List<Purchase> purchases) {
        if (resultCode == BillingClient.BillingResponse.OK) {
            for (Purchase purchase : purchases) {
                handlePurchase(purchase);
            }
            mBillingUpdatesListener.onPurchasesUpdated(mPurchases);
        } else if (resultCode == BillingClient.BillingResponse.USER_CANCELED) {
            Log.i(TAG, "onPurchasesUpdated() - user cancelled the purchase flow - skipping");
        } else {
            Log.w(TAG, "onPurchasesUpdated() got unknown resultCode: " + resultCode);
        }
    }