2

以下代码适用于我的生产应用程序中的所有手机,运行 4.1.2 的 Galaxy Nexus 除外。Play商店给我发了错误,我先贴代码,再贴错误:

    // Roughly formats the currency by loping off the decimal places (amount
// comes already rounded)
public static String formatCurrencyRound(double amount) {
    String currency = formatCurrency(amount); // Returns "$8.00"

    return currency.substring(0, currency.indexOf("."));
}

错误:

java.lang.RuntimeException: Unable to resume activity {com.ootpapps.saving.made.simple/com.ootpapps.saving.made.simple.SavingsPlanOverview}: java.lang.StringIndexOutOfBoundsException: length=9; regionStart=0; regionLength=-1
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.StringIndexOutOfBoundsException: length=9; regionStart=0; regionLength=-1
at java.lang.String.startEndAndLength(String.java:593)
at java.lang.String.substring(String.java:1474)
at com.ootpapps.saving.made.simple.App.formatCurrencyRound(App.java:68)
at com.ootpapps.saving.made.simple.SavingsPlanOverview.updateSavingsPlanWidgets(SavingsPlanOverview.java:224)
at com.ootpapps.saving.made.simple.SavingsPlanOverview.onResume(SavingsPlanOverview.java:156)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
at android.app.Activity.performResume(Activity.java:5082)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)
... 12 more

如果有人可以提出一种更好的方法来四舍五入这个货币字符串,或者,一种更好的方法将原始数字四舍五入为没有小数的格式化字符串,我将不胜感激。同样,由于某种原因,这仅在运行 4.1.2 的 GNexus 上失败。

谢谢!

编辑添加格式货币代码:

public static String formatCurrency(double amount) {
    NumberFormat currency = NumberFormat.getCurrencyInstance();

    return currency.format(amount);
}

编辑续 -我使用的代码可以将货币四舍五入到整美元

public static String formatCurrencyWhole(double amount) {
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    currency.setMaximumFractionDigits(0);
    currency.setMinimumFractionDigits(0);

    return currency.format(amount);
}
4

2 回答 2

2

首先,永远不应该使用s 来处理double货币。你应该使用BigDecimal来保持精度。(有关更多信息,请参阅此问题。)

除此之外,您可以使用NumberFormat来获取您的String代表:

NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
String result = format.format(amount);

.format()拿双; 如果您最终使用BigDecimal,请使用bigDecimal.doubleValue(). 该答案提供了该领域的一些其他详细信息。

于 2012-10-19T03:10:50.503 回答
2

我认为字符串的格式已经是 $8

如果小数不存在:

currency.substring(0, currency.indexOf("."));

将抛出 IndexOutOfBoundsException。

解决方案可能就像事先测试小数一样简单。

public static String formatCurrencyRound(double amount) { String currency = formatCurrency(amount); // 返回“$8.00”

if(currency.indexOf(".") != -1){
   return currency.substring(0, currency.indexOf("."));
}else{
   return currency;
}

}

- - - - 编辑 - - - - -

正如 Ken(非常聪明的人)在评论中指出的那样,堆栈跟踪中的关键行是:

java.lang.StringIndexOutOfBoundsException:长度=9;区域开始=0;regionLength=-1 在 java.lang.String.startEndAndLength(String.java:593)

此错误显示 regionLength = -1,这意味着 indexOf(".") 的结果为 -1。((“。”)不存在)

它还显示字符串长度为 9,这让我认为不同的分隔符问题(Ken 也指出)可能是真正的问题。除非美元金额在 $10000000 范围内。

这就是为什么我想查看 formatCurrency(Double); 的代码的原因。

- - -编辑 - - -

怀疑您使用的是默认语言环境:

NumberFormat 货币 = NumberFormat.getCurrencyInstance();

文档对此有这样的说法:

http://developer.android.com/reference/java/util/Locale.html

“默认语言环境不适合机器可读的输出。最好的选择通常是 Locale.US - 这个语言环境保证在所有设备上都可用,而且它没有令人惊讶的特殊情况并且经常使用(尤其是对于计算机-计算机通信)意味着它也往往是最有效的选择。

一个常见的错误是在生成机器可读的输出时隐式使用默认语言环境。这往往适用于开发人员的测试设备(特别是因为很多开发人员使用 en_US),但在用户处于更复杂区域设置的设备上运行时会失败。”

除非您的应用需要外币,否则请使用:

NumberFormat 货币 = NumberFormat.getCurrencyInstance(Locale.US);

于 2012-10-19T03:24:46.560 回答