7

我使用以下代码从 Google Play In-app Billing 解析价格:

private static Number parsePrice(String priceFromGoogle) {
    Locale currencyLocale = getCurrencyLocale(priceFromGoogle);
    NumberFormat numberFormat = NumberFormat.getCurrencyInstance(currencyLocale);
    Number number = null;
    try {
        number = numberFormat.parse(priceFromGoogle);
    } catch (ParseException e) {
        e.printStackTrace(); 
    }
    return number;
} 

private Locale getCurrencyLocale(String price) {
    Locale locale = null;
    for (Locale availableLocale : Locale.getAvailableLocales()) {
        NumberFormat numberFormat = NumberFormat.getCurrencyInstance(availableLocale);
        try {
            numberFormat.parse(price);
            locale = availableLocale;
            break;
        } catch (ParseException e) {
            //do nothing
        }
    }
    return locale;
}

它在我的测试设备和我的语言环境中运行良好。但在某些设备和某些国家/地区,我会遇到这样的价格:“Php1,337.07”、“US$ 29.99”、“MX$374.79”。我的方法在这种情况下不起作用。

有没有解决这个问题的通用方法?

4

3 回答 3

9
于 2014-02-07T15:13:09.370 回答
9

检查他们的应用内计费示例项目并修改 SkuDetails.java 以便您也可以获得该信息:

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Represents an in-app product's listing details.
 */
public class SkuDetails {
    String mItemType;
    String mSku;
    String mType;
    int mPriceAmountMicros;
    String mPriceCurrencyCode;
    String mPrice;
    String mTitle;
    String mDescription;
    String mJson;

    public SkuDetails(String jsonSkuDetails) throws JSONException {
        this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails);
    }

    public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException {
        mItemType = itemType;
        mJson = jsonSkuDetails;
        JSONObject o = new JSONObject(mJson);
        mSku = o.optString("productId");
        mType = o.optString("type");
        mPrice = o.optString("price");
        mPriceAmountMicros = o.optInt("price_amount_micros");
        mPriceCurrencyCode = o.optString("price_currency_code");
        mTitle = o.optString("title");
        mDescription = o.optString("description");
    }

    public String getSku() { return mSku; }
    public String getType() { return mType; }
    public String getPrice() { return mPrice; }
    public String getTitle() { return mTitle; }
    public String getDescription() { return mDescription; }
    public int getPriceAmountMicros() { return mPriceAmountMicros; }
    public String getPriceCurrencyCode() { return mPriceCurrencyCode; }

    @Override
    public String toString() {
        return "SkuDetails:" + mJson;
    }
}
于 2014-10-10T10:45:30.687 回答
4

由于 Google Play 可能会以 java.text.NumberFormat 不支持的货币格式返回价格,因此我编写了自己的实现

public class Price {
private double value;
private String currency;
private String pattern;
private DecimalFormat decimalFormat;

private Price() {}

private static String currencyToDecimalFormat(String value, Price price) {
    char decimalSeparator = '.';
    char groupingSeparator = 0;
    if (value.length() >= 3) {
        char[] chars = value.toCharArray();
        if (chars[chars.length - 2] == ',') {
            decimalSeparator = ',';
            chars[chars.length - 2] = '.';
        } else if (chars[chars.length - 3] == ',') {
            decimalSeparator = ',';
            chars[chars.length - 3] = '.';
        }
        value = new String(chars);
    }

    if (value.contains(",")) {
        groupingSeparator = ',';
        value = value.replaceAll(",", "");
    } else if (value.contains(" ")) {
        groupingSeparator = ' ';
        value = value.replaceAll(" ", "");
    } else if (value.contains("\u00A0")) {
        groupingSeparator = '\u00A0';
        value = value.replaceAll("\u00A0", "");
    }

    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
    if (groupingSeparator != 0) {
        price.decimalFormat = new DecimalFormat("###,###.00");
        symbols.setGroupingSeparator(groupingSeparator);
    } else {
        price.decimalFormat = new DecimalFormat("######.00");
    }

    symbols.setDecimalSeparator(decimalSeparator);
    price.decimalFormat.setDecimalFormatSymbols(symbols);
    return value.replaceAll(",", "");
}

public static Price parsePrice(String priceFromGoogle) {
    Price price = new Price();
    StringBuilder patternBuilder = new StringBuilder();
    Pattern pattern = Pattern.compile("(?:[0-9]{1,3})(?:[0-9,.\\s\u00A0]+)");
    Matcher matcher = pattern.matcher(priceFromGoogle);
    matcher.find();
    String priceString = matcher.group();
    if (priceFromGoogle.indexOf(priceString) == 0) {
        if (priceFromGoogle.length() != priceString.length()) {
            price.currency = priceFromGoogle.substring(priceString.length());
        } else {
            price.currency = "";
        }
    } else {
        price.currency = priceFromGoogle.substring(0, priceFromGoogle.indexOf(priceString));
    }
    price.currency = price.currency.trim();


    if (priceFromGoogle.startsWith(price.currency)) {
        patternBuilder.append("%1s");
        char nextChar = priceFromGoogle.charAt(price.currency.length());
        if (nextChar == ' ' || nextChar == 0xA0) {
            patternBuilder.append(' ');
        }
        patternBuilder.append("%2$s");
    } else {
        patternBuilder.append("%2$s");
        char prevChar = priceFromGoogle.charAt(priceFromGoogle.indexOf(price.currency) - 1);
        if (prevChar == ' ' || prevChar == 0xA0) {
            patternBuilder.append(' ');
        }
        patternBuilder.append("%1s");
    }
    price.pattern = patternBuilder.toString();

    priceString = trim(priceString);

    priceString = currencyToDecimalFormat(priceString, price);

    price.value = Double.parseDouble(priceString);
    return price;
}

@Override
public String toString() {
    if (pattern != null) {
        return String.format(pattern, currency, decimalFormat.format(value));
    } else {
        return "";
    }
}

}

编辑1:

由于 Google 使用不间断空间而不是通常的空间,您需要检查这一点并使用自定义修剪功能:

public static String trim(String text) {
    int start = 0, last = text.length() - 1;
    int end = last;
    while ((start <= end) && (text.charAt(start) <= ' ' || text.charAt(start) == 0xA0)) {
        start++;
    }
    while ((end >= start) && (text.charAt(end) <= ' ' || text.charAt(end) == 0xA0)) {
        end--;
    }
    if (start == 0 && end == last) {
        return text;
    }
    return text.substring(start, end);
}
于 2013-09-02T07:26:06.153 回答