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 でのみ失敗します。

ありがとう!

編集 追加された formatCurrency コード:

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を使用して処理されるべきではありませ。精度を保つために使用する必要があります。(詳細については、この質問を参照してください。)doubleBigDecimal

それはさておき、表現NumberFormatを取得するために使用できますString

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

.format()double を取ります。を使用する場合はBigDecimal、 を使用してくださいbigDecimal.doubleValue()この回答は、この分野の追加の詳細を提供します。

于 2012-10-19T03:10:50.503 に答える
2

I think the format of the string was already $8

If the decimal doesn't exist:

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

Will throw an IndexOutOfBoundsException.

The solution may be as simple as testing for the decimal before hand.

public static String formatCurrencyRound(double amount) { String currency = formatCurrency(amount); // Returns "$8.00"

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

}

------- EDIT ----------

As Ken (very smart guy) pointed out in the comments the key line in the stack trace is:

java.lang.StringIndexOutOfBoundsException: length=9; regionStart=0; regionLength=-1 at java.lang.String.startEndAndLength(String.java:593)

This error shows regionLength = -1 which means that the result of indexOf(".") was -1. ((".") didn't exist)

It also shows a string length of 9 which is what makes me think that the different seperator issue (that Ken also pointed out) might be the real problem. Unless the dollar amount was in the $10000000 range.

That's why I would like to see the code for formatCurrency(Double);

-----EDIT-----

As suspected you are using the default locale:

NumberFormat currency = NumberFormat.getCurrencyInstance();

The documentation has this to say about that:

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

"The default locale is not appropriate for machine-readable output. The best choice there is usually Locale.US – this locale is guaranteed to be available on all devices, and the fact that it has no surprising special cases and is frequently used (especially for computer-computer communication) means that it tends to be the most efficient choice too.

A common mistake is to implicitly use the default locale when producing output meant to be machine-readable. This tends to work on the developer's test devices (especially because so many developers use en_US), but fails when run on a device whose user is in a more complex locale."

Unless foreign currency is required by your app, use:

NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.US);

于 2012-10-19T03:24:46.560 に答える