[Android订阅购买AccountHold为空

问题描述 投票:0回答:1

我正在使用正式的google示例代码进行用户订阅play-billing-sample。切换Google帐户时,我在检查帐户持有状态时得到了nullpointexception(我的手机有两个注册为测试帐户的Google帐户以测试购买)。

  1. 我没有任何问题地登录第一个帐户并购买了基本或高级订阅
  2. 当我切换到第二个帐户时,出现以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference at com.pishimishi.test.classytaxijava.billing.BillingUtilities.isAccountHold(BillingUtilities.java:151)

BillingUtilities.java:

/**
     * Returns true if account hold should be shown.
     */
    public static boolean isAccountHold(SubscriptionStatus subscription) {
        return subscription != null &&
                !subscription.isEntitlementActive &&
                subscription.isAccountHold &&
                !subscription.subAlreadyOwned;
    }

和SubscriptionStatus.java:

/**
 * Local subscription data. This is stored on disk in a database.
 */
@Entity(tableName = "subscriptions")
public class SubscriptionStatus {
    public class SubscriptionStatusList {
        @Nullable
        @SerializedName("subscriptions")
        List<SubscriptionStatus> subscriptionStatuses;

        SubscriptionStatusList(@Nullable List<SubscriptionStatus> subscriptionStatuses) {
            this.subscriptionStatuses = subscriptionStatuses;
        }
    }

    public static final String SUBSCRIPTIONS_KEY = "subscriptions";
    public static final String SKU_KEY = "sku";
    public static final String PURCHASE_TOKEN_KEY = "purchaseToken";
    public static final String IS_ENTITLEMENT_ACTIVE_KEY = "isEntitlementActive";
    public static final String WILL_RENEW_KEY = "willRenew";
    public static final String ACTIVE_UNTIL_MILLISEC_KEY = "activeUntilMillisec";
    public static final String IS_FREE_TRIAL_KEY = "isFreeTrial";
    public static final String IS_GRACE_PERIOD_KEY = "isGracePeriod";
    public static final String IS_ACCOUNT_HOLD_KEY = "isAccountHold";

    // Local fields
    @PrimaryKey(autoGenerate = true)
    public int primaryKey = 0;
    @Nullable
    public String subscriptionStatusJson;
    public boolean subAlreadyOwned;
    public boolean isLocalPurchase;

    // Remote fields
    @Nullable
    public String sku;
    @Nullable
    public String purchaseToken;
    public Boolean isEntitlementActive;
    public Boolean willRenew;
    public Long activeUntilMillisec = 0L;
    public Boolean isFreeTrial;
    public Boolean isGracePeriod;
    public Boolean isAccountHold;

    /**
     * Parse subscription data from Map and return null if data is not valid.
     */
    @Nullable
    public static List<SubscriptionStatus> listFromMap(Map<String, Object> map) {
        List<SubscriptionStatus> subscriptions = new ArrayList<>();

        List<Map<String, Object>> subList = null;

        if (map.get(SUBSCRIPTIONS_KEY) instanceof ArrayList) {
            subList = (ArrayList) map.get(SUBSCRIPTIONS_KEY);
        }

        if (subList == null) {
            return null;
        }

        for (Map<String, Object> subStatus : subList) {
            SubscriptionStatus subscriptionStatus = new SubscriptionStatus();

            subscriptionStatus.sku = (String) subStatus.get(SKU_KEY);
            subscriptionStatus.purchaseToken = (String) subStatus.get(PURCHASE_TOKEN_KEY);
            subscriptionStatus.isEntitlementActive =
                    (Boolean) subStatus.get(IS_ENTITLEMENT_ACTIVE_KEY);
            subscriptionStatus.willRenew = (Boolean) subStatus.get(WILL_RENEW_KEY);
            subscriptionStatus.activeUntilMillisec =
                    (Long) subStatus.get(ACTIVE_UNTIL_MILLISEC_KEY);
            subscriptionStatus.isFreeTrial = (Boolean) subStatus.get(IS_FREE_TRIAL_KEY);
            subscriptionStatus.isGracePeriod = (Boolean) subStatus.get(IS_GRACE_PERIOD_KEY);
            subscriptionStatus.isAccountHold = (Boolean) subStatus.get(IS_ACCOUNT_HOLD_KEY);

            subscriptions.add(subscriptionStatus);
        }

        return subscriptions;
    }

    /**
     * Parse subscription data from String and return null if data is not valid.
     */
    @Nullable
    public static List<SubscriptionStatus> listFromJsonString(String dataString) {
        Gson gson = new Gson();
        try {
            SubscriptionStatusList subscriptionStatusList =
                    gson.fromJson(dataString, SubscriptionStatusList.class);
            if (subscriptionStatusList != null) {
                return subscriptionStatusList.subscriptionStatuses;
            } else {
                return null;
            }
        } catch (JsonSyntaxException e) {
            return null;
        }
    }

    /**
     * Create a record for a subscription that is already owned by a different user.
     *
     * The server does not return JSON for a subscription that is already owned by
     * a different user, so we need to construct a local record with the basic fields.
     */
    public static SubscriptionStatus alreadyOwnedSubscription(String sku, String purchaseToken) {
        SubscriptionStatus subscriptionStatus = new SubscriptionStatus();
        subscriptionStatus.sku = sku;
        subscriptionStatus.purchaseToken = purchaseToken;
        subscriptionStatus.isEntitlementActive = false;
        subscriptionStatus.subAlreadyOwned = true;
        return subscriptionStatus;
    }

    @Override
    public String toString() {
        return "SubscriptionStatus{" +
                "primaryKey=" + primaryKey +
                ", subscriptionStatusJson='" + subscriptionStatusJson + '\'' +
                ", subAlreadyOwned=" + subAlreadyOwned +
                ", isLocalPurchase=" + isLocalPurchase +
                ", sku='" + sku + '\'' +
                ", purchaseToken='" + purchaseToken + '\'' +
                ", isEntitlementActive=" + isEntitlementActive +
                ", willRenew=" + willRenew +
                ", activeUntilMillisec=" + activeUntilMillisec +
                ", isFreeTrial=" + isFreeTrial +
                ", isGracePeriod=" + isGracePeriod +
                ", isAccountHold=" + isAccountHold +
                '}';
    }
}

我不明白为什么我必须获得NPE。或者,如果我们从服务器上获取信息,为什么我不使用第一个帐户获取它(我甚至测试了暂停第一个帐户的购买)并且可以正常工作。

PS。最初,在我的游戏控制台中,“帐户保留”功能未激活,但是后来,我激活了“帐户保留和帐户暂停”功能。但是切换到第二个Google帐户后,我仍然收到相同的错误。

java android nullpointerexception in-app-purchase in-app-billing
1个回答
0
投票

每次Java在if语句中使用Boolean对象时,它都会将其解包为使用boolean方法的Boolean.booleanValue()类型的基本类型。]

要解决此问题,您必须将isAccountHoldisEntitlementActive类型从Boolean

更改为boolean。如果这些字段必须为Boolean类型,请在以下条件之前检查它们是否为null:
public static boolean isAccountHold(SubscriptionStatus subscription) {
    return subscription != null &&
            (subscription.isEntitlementActive == null || !subscription.isEntitlementActive) &&
            (subscription.isAccountHold != null || subscription.isAccountHold) &&
            !subscription.subAlreadyOwned;
}
© www.soinside.com 2019 - 2024. All rights reserved.