Potential Bug Triggers in Android Development Due to Regional Preferences
Introduction
I am Hand-Tomi and I work on developing my route for Android at KINTO Technologies.
It has been almost a year since Android 14 was released on April 12, 2023. However, I feel that the concept of "Regional Preferences" on Android remains unclear to many. That is why in this article I've chosen to delve into this topic.
Developing multilingual applications without understanding "Regional Settings" can lead to the risk of encountering unforeseen bugs. I hope this article will be of help to readers mitigating these risks.
Key Points Covered in This Article
Locale.getDefault() == Locale.JAPAN
Code description
Locale
: Classes representing specific cultural and geographic settings based on language, country, or regionLocale.getDefault()
: Returns the defaultLocale
for the current applicationLocale.JAPAN
: Instances of locale representing Japanese language (ja
) and country (JP
) Preferences
Does the above code output true
if the device is set to Japanese (Japan)? Or does it output false
?
The correct answer is true
on Android 13 and below, and unknownfor Android 14 and above with this much information.
This article explains why it is unknown for Android 14 and above!
Locale
on Android?
What is Locale
is a class that represents a cultural or geographic setting based on language, country, or region. Using this information, Android applications can be configured to adapt applications to diverse users.
Locale
deals mainly with languages and countries, but more data can be extracted by using LocalePreferences
.
val locale = Locale.getDefault()
println("calendarType = ${LocalePreferences.getCalendarType(locale)}")
println("firstDayOfWeek = ${LocalePreferences.getFirstDayOfWeek(locale)}")
println("hourCycle = ${LocalePreferences.getHourCycle(locale)}")
println("temperatureUnit = ${LocalePreferences.getTemperatureUnit(locale)}")
If you execute the above code on a device with "Japanese (Japan)" Preferences, it will appear as follows.
calendarType = gregorian
: Calendar method = Gregorian calendarfirstDayOfWeek = sun
: First day of the week = SundayhourCycle = h23
: Time cycle = 0-23temperatureUnit = celsius
: Temperature = Celsius
What is "Regional Preferences"?
Introduced in Android 14, the "Regional Preferences" feature allows you to customize the "temperature" and "First day of week" set by Locale (language and country).
- Temperature
- Use app default
- Celsius (°C)
- Fahrenheit (°F)
- First day of week
- Use app default
- Monday to Sunday
Temperature setting screen | First day of the week screen |
---|---|
How to go to the settings
The "Regional Preferences" screen can be accessed from the "System" > "Language" section within the "Preferences App."
Why do we need "Regional Preferences"?
Both the "United States" and the "Netherlands" can use English, but the unit of "temperature" used and the "first day of the week" are different.
United States | Netherlands | |
---|---|---|
Temperature | Fahrenheit | Celsius |
First day of week | Sunday | Monday |
If a Dutch person living in the United States is accustomed to Celsius and wants to change the temperature only to Celsius, "Regional Preferences" can be used to accomplish this.
What changes would be made if you set "Regional Preferences"?
Locale.getDefault().toString()
To check the setting values, let's change each setting while using the code above.
Language | Temperature | First day of week | Results |
---|---|---|---|
Japanese (Japan) | Default | Default | ja_JP |
Japanese (Japan) | Fahrenheit | Default | ja_JP_#u-mu-fahrenhe |
Japanese (Japan) | Default | Monday | ja_JP_#u-fw-sun |
Japanese (Japan) | Fahrenheit | Monday | ja_JP_#u-fw-sun-mu-fahrenhe |
Setting "Temperature" and "First day of the week" resulted in incomprehensible text output such as #u
, mu-fahrenhe
and fw-sun
, which are member variables of Locale
and localeExtensions< 5} values. Thus, if a value is set for
localeExtensions, the results of
hashCodeand
equals()for
Localewill also change. Comparing to
Locale.JAPANdoes not result in
true`.
Then, how do we check the language?
Locale.getDefault() == Locale.JAPAN // X
Locale.getDefault().language == Locale.JAPANESE.language // O
If you want to check the language, compare with the language
property included in Locale
. By using this method, I believe you can get the results you are looking for without being affected by changing the "Regional Preferences."
Conclusion
It is quite difficult to detect this change, even if the previously working code suddenly stops working due to the "Regional Preferences" feature secretly added from Android 14. Most people will have no problem, but if you are comparing languages in Locale instances, please ensure to check. If as many people as possible can find and solve such bugs quickly, this article will be a great success!
Check out other articles written by my route team members!
- Structured Concurrency with Kotlin coroutines
- Jetpack Compose in myroute Android App
- A Beginner’s Story of Inspiration With Compose Preview
Thank you for reading my article all the way to the end.
*The Android robot was reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.
関連記事 | Related Posts
The story of how I struggled with the character code when I got OGP in Kotlin
KotlinでOGPを取得する時に文字コードで苦労した話
KINTOテクノロジーズにおける言語ローカライゼーション(前編)
Language Localization at KINTO Technologies (Part 1)
Mobile App Development Using Kotlin Multiplatform Mobile (KMM) and Compose Multiplatform
Language Support in Vuetify and NuxtJS
We are hiring!
【iOS/Androidエンジニア】モバイルアプリ開発G/東京
モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。
【iOSエンジニア】モバイルアプリ開発G/大阪
モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。