About a simple mistake that can be made in the use of
String.format. To illustrate this very common mistake, some android code from the
This code can be found here: https://android.googlesource.com/platform/packages/providers/ContactsProvider/
String.format allows formatting of Strings according to the following documentation http://developer.android.com/reference/java/util/Formatter.html
This is sometimes used for formatting SQLite queries in android. In particular, this is used in the
However, there is a pitfall in the use of
String.format to format SQL queries.
Until Gingerbread release, the following lines are present in
mRawContactsQueryByRawContactId = String.format( RawContactsQuery.SQL_FORMAT_BY_RAW_CONTACT_ID, MimeTypeIdPhoto, mMimeTypeIdPhone);
SQL_FORMAT_BY_RAW_CONTACT_ID contains 2
%d to be replaced by numbers in the
Here is the trap.
- SQLite will expect these values to be Latin numbers or column names, because they are not quoted.
- String.format uses the current locale unless explicitly specified.
- In Arabic, %d results in Arabic numbers such as ١٢٣…
Conclusion: If your locale is Arabic, SQLite searches for a column named after an Arabic number, which does not exist, and crashes. This kind of issue will go totally unnoticed until you test your app with an Arabic locale.
Formatter documentation clearly states this under the Number localization paragraph.
The solution to avoid this is to force the locale to, for instance
Locale.US. Incidentally, this is the solution implemented in ICS.
mRawContactsQueryByRawContactId = String.format(Locale.US RawContactsQuery.SQL_FORMAT_BY_RAW_CONTACT_ID, mMimeTypeIdPhoto, mMimeTypeIdPhone);