0

Ok, So I read a couple other questions with this same error, but none have been answered as working, and doesnt seem like I can get it working. I am connecting to google in-app billing and have everything set up, but, when I try to pull my skudetails (I have 2 SKUs there now), I get the error - Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

I have a SubscriptionActivity, Result (serializable), and Details model class (serializable). Below is the code, any help will be great, thanks-

From subscriptionactivity:

Gson gson = new Gson();
try {
    Result result = gson.fromJson(skuDetailsList.toString(), Result.class);
    if (result != null) {
        for (Details d : result.getDetails()) {
            System.out.println(d.getProductId()
                + " \n " + d.getTitle() + " \n " + d.getDescription() + " \n "
                + d.getPrice());
        }
    }
} catch (NumberFormatException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

From details model:

public class Details implements Serializable{

    @SerializedName("productId")
    @Expose
    private String productId;
    @SerializedName("type")
    @Expose
    private String type;
    @SerializedName("price")
    @Expose
    private String price;
    @SerializedName("price_amount_micros")
    @Expose
    private Integer priceAmountMicros;
    @SerializedName("price_currency_code")
    @Expose
    private String priceCurrencyCode;
    @SerializedName("subscriptionPeriod")
    @Expose
    private String subscriptionPeriod;
    @SerializedName("freeTrialPeriod")
    @Expose
    private String freeTrialPeriod;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("description")
    @Expose
    private String description;

    public String getProductId() {
        return productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public Integer getPriceAmountMicros() {
        return priceAmountMicros;
    }

    public void setPriceAmountMicros(Integer priceAmountMicros) {
        this.priceAmountMicros = priceAmountMicros;
    }

    public String getPriceCurrencyCode() {
        return priceCurrencyCode;
    }

    public void setPriceCurrencyCode(String priceCurrencyCode) {
        this.priceCurrencyCode = priceCurrencyCode;
    }

    public String getSubscriptionPeriod() {
        return subscriptionPeriod;
    }

    public void setSubscriptionPeriod(String subscriptionPeriod) {
        this.subscriptionPeriod = subscriptionPeriod;
    }

    public String getFreeTrialPeriod() {
        return freeTrialPeriod;
    }

    public void setFreeTrialPeriod(String freeTrialPeriod) {
        this.freeTrialPeriod = freeTrialPeriod;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

}

From Result activity:

public class Result implements Serializable{
    @SerializedName("SkuDetails")
    @Expose
    private ArrayList<Details> details = new ArrayList<Details>();
    /**
     *
     * @return The SkuDetails
     */
    public ArrayList<Details> getDetails() {
        return details;
    }
    /**
     *
     * @param details
     * The details
     */
    public void setDetails(ArrayList<Details> details) {
        this.details = details;
    }
}*

Oh..and the response I was trying to parse (skuDetailsList.toString()) is:

[
    SkuDetails: {
        "productId": "basic_sub",
        "type": "subs",
        "price": "$0.99",
        "price_amount_micros": 990000,
        "price_currency_code": "USD",
        "subscriptionPeriod": "P1M",
        "freeTrialPeriod": "P4W2D",
        "title": "Basic Subscription Service (DadBod Recipes)",
        "description": "Basic Subscription Service for DadBodRecipes"
    },
    SkuDetails: {
        "productId": "enterprise_sub",
        "type": "subs",
        "price": "$2.99",
        "price_amount_micros": 2990000,
        "price_currency_code": "USD",
        "subscriptionPeriod": "P1M",
        "freeTrialPeriod": "P4W2D",
        "title": "Enterprise Subscription Service (DadBod Recipes)",
        "description": "Enterprise Subscription Service for DadBodRecipes"
    }
]
pirho
  • 11,565
  • 12
  • 43
  • 70

2 Answers2

0

Issue is because, the result you're getting is as <Key-Value> pair (not as JSON object/Array, but similar to it).

So you'll need to make it to JSONObject first and then parse it using Gson like below:

Map<String, String> params = skuDetailsList;
JSONObject object = new JSONObject(params);
Result result = gson.fromJson(object.toString(), Result.class);

Do like this, hope it helps !

Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58
  • Hi, Thanks, it being key/value makes sense. I put in the snippet you added but it wants to reformat. You gave - Map params = skuDetailsList; But it is saying - incompatible types (because skuDetailsList is a List, not a Map). I tried casting - Map params = (Map) skuDetailsList; But it broke with java.util.ArrayList cannot be cast to java.util.Map – Eric Krusznis Oct 09 '18 at 13:46
  • @EricKrusznis I didn't know about what **`skuDetailsList`** was before, but now you're saying that it's **`List`**. so, it's clear from now that we can't cast list to map, so what i'll suggest you is that try casting your response from your callback as Map directly and it'll work. – Jeel Vankhede Oct 09 '18 at 13:56
  • Thanks, The problem here is that the response is not just one 'SkuDetails' but as many as needed. So the keys will actually be duplicated – Eric Krusznis Oct 09 '18 at 14:11
0

You are trying to parse your json

[

as

{

when you see the [ it represents a list

when you see the { it represents an object.

I'm pretty sure you know that as you built a wrapper class, but your wrapper class is also an object, not an array.

So your choices are to have your wrapper class extend ArrayList or some form of List.

Or

Tell your Json converter that the base is an Array and you want the first object in the list is an object of your type.

Sam
  • 5,342
  • 1
  • 23
  • 39
  • Hi, Thanks, so I tried changing my model (and result class for good measure) to implement a List. I am not getting a similar error - IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 2 path $[0] – Eric Krusznis Oct 09 '18 at 14:09
  • did you remove your serializable name skuData? as your Result class should extend ArrayList type and it will automatically have your skudata items inside itself as it is an arraylist. – Sam Oct 09 '18 at 14:21