Android покупка подписки AccountHold имеет значение null - PullRequest
0 голосов
/ 05 мая 2020

Я использую официальный пример кода Google для подписки пользователя play-billing-sample . Я получаю nullpointexception при проверке удержания учетной записи при переключении учетных записей Google (на моем телефоне две учетные записи Google, зарегистрированные как тестовые учетные записи для проверки покупок).

  1. Я без проблем вхожу в первую учетную запись и покупаю базовые c или премиальные подписки
  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. Или, если мы получаем if с сервера, почему бы мне не получить его с первой учетной записью (я даже тестировал приостановку покупки для первой учетной записи), и это работает.

PS. Первоначально в моей игровой консоли функция удержания учетной записи не была активна, но позже я активировал функцию приостановки и приостановки учетной записи. Но все равно я получаю ту же ошибку сразу после переключения на вторую учетную запись Google.

1 Ответ

0 голосов
/ 05 мая 2020

Каждый раз, когда Java использует объект Boolean в операторе if , он разворачивает его в примитив, который имеет тип boolean с помощью метода Boolean.booleanValue().

Чтобы исправить проблему вам нужно изменить типы isAccountHold и isEntitlementActive с 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...