FC2ブログ

「ListPreference.getSummary」がAndroid 2.3までと3.0以上で挙動が違う件 

少し前の話になりますが、自作Androidアプリ『騰落レシオ通知』のバージョンアップ時に、Android 4.1のエミュレータを軽い気持ちで試したみたところ、まさかのエラー発生;

参考までに対処方法をメモしておきます。

下記の通り、本来は2.3みたく赤枠部分をタップすると設定画面に遷移しますが、4.1だとエラーで落ちてしまいます。
また、正常/異常の境界となるバージョンはどこか試したところ、2.3と3.0の間でした。

【2.3の場合】
20130521_ListPreference_getSummary_2_3

【4.1の場合】
20130521_ListPreference_getSummary_4_1

その際のエラーログは下記の通りです。
(エラー発生時刻は省略)


E/AndroidRuntime(781): FATAL EXCEPTION: main
E/AndroidRuntime(781): java.util.UnknownFormatConversionException: Conversion:
E/AndroidRuntime(781): at java.util.Formatter$FormatSpecifierParser.unknownFormatConversionException(Formatter.java:2304)
E/AndroidRuntime(781): at java.util.Formatter$FormatSpecifierParser.advance(Formatter.java:2298)
E/AndroidRuntime(781): at java.util.Formatter$FormatSpecifierParser.parseConversionType(Formatter.java:2377)
E/AndroidRuntime(781): at java.util.Formatter$FormatSpecifierParser.parseArgumentIndexAndFlags(Formatter.java:2348)
E/AndroidRuntime(781): at java.util.Formatter$FormatSpecifierParser.parseFormatToken(Formatter.java:2281)
E/AndroidRuntime(781): at java.util.Formatter.doFormat(Formatter.java:1069)
E/AndroidRuntime(781): at java.util.Formatter.format(Formatter.java:1040)
E/AndroidRuntime(781): at java.util.Formatter.format(Formatter.java:1009)
E/AndroidRuntime(781): at java.lang.String.format(String.java:1998)
E/AndroidRuntime(781): at java.lang.String.format(String.java:1972)
E/AndroidRuntime(781): at android.preference.ListPreference.getSummary(ListPreference.java:152)
E/AndroidRuntime(781): at android.preference.Preference.onBindView(Preference.java:522)
E/AndroidRuntime(781): at android.preference.Preference.getView(Preference.java:460)
E/AndroidRuntime(781): at android.preference.PreferenceGroupAdapter.getView(PreferenceGroupAdapter.java:221)
E/AndroidRuntime(781): at android.widget.AbsListView.obtainView(AbsListView.java:2271)
E/AndroidRuntime(781): at android.widget.ListView.makeAndAddView(ListView.java:1769)
E/AndroidRuntime(781): at android.widget.ListView.fillDown(ListView.java:672)
E/AndroidRuntime(781): at android.widget.ListView.fillFromTop(ListView.java:733)
E/AndroidRuntime(781): at android.widget.ListView.layoutChildren(ListView.java:1622)
E/AndroidRuntime(781): at android.widget.AbsListView.onLayout(AbsListView.java:2106)
E/AndroidRuntime(781): at android.view.View.layout(View.java:13754)
E/AndroidRuntime(781): at android.view.ViewGroup.layout(ViewGroup.java:4364)
E/AndroidRuntime(781): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
E/AndroidRuntime(781): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
E/AndroidRuntime(781): at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)


なお、ログに自分のアプリ名は出力されていません。
そのため、ログを上から順に読んでいって心当たりのある箇所を探すことに。

結局、原因は13行目の「ListPreference.getSummary」でした。
Androidのソースを確認したところ、3.0からはgetSummary内で、

String.format(String format, Object... args)

を呼ぶように変わっていました。

アプリ内のsetSummaryでサマリー(上図【2.3の場合】の黄枠部分)にパーセンテージを表す「%」を設定していましたが、それが表示される際に、AndroidのフレームワークでgetSummaryが実行され、その中のformatが「%」をうまく解釈できずにエラーが発生しているようでした。

ここまで分かれば、後は修正するだけ。

下記サイトを参考にさせていただき、アプリが稼働するバージョンを判定して、
2.3以下の場合は「%」をそのまま、
3.0より大きい場合は「%」をエスケープして「%%」として設定しました。

以上、何かのお役に立てれば幸いです☆

稼働中の端末のPlatform(API level・バージョン) を取得する↓
http://androyer.blogspot.jp/2012/02/platformapi-level.html?m=1