diff --git a/android/modules/locale/src/java/ti/modules/titanium/locale/LocaleModule.java b/android/modules/locale/src/java/ti/modules/titanium/locale/LocaleModule.java index d76653ce3dc..e3f03d61df1 100644 --- a/android/modules/locale/src/java/ti/modules/titanium/locale/LocaleModule.java +++ b/android/modules/locale/src/java/ti/modules/titanium/locale/LocaleModule.java @@ -10,8 +10,10 @@ import java.text.DateFormat; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Iterator; import java.util.Locale; +import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollModule; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; @@ -21,8 +23,12 @@ import org.appcelerator.titanium.util.TiPlatformHelper; import org.appcelerator.titanium.util.TiRHelper; +import android.os.Build; import android.telephony.PhoneNumberUtils; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.os.LocaleListCompat; + @Kroll.module public class LocaleModule extends KrollModule { @@ -33,6 +39,62 @@ public LocaleModule() super("Locale"); } + @Kroll.setProperty + public void setApplicationLocales(String locales) + { + if (Build.VERSION.SDK_INT < 33) { + Log.w(TAG, "This property is only supported on Android API level 33 and above."); + return; + } + LocaleListCompat appLocale = LocaleListCompat.forLanguageTags(locales); + AppCompatDelegate.setApplicationLocales(appLocale); + } + + @Kroll.getProperty + public KrollDict[] getApplicationLocales() + { + if (Build.VERSION.SDK_INT < 33) { + Log.w(TAG, "This property is only supported on Android API level 33 and above."); + return new KrollDict[0]; + } + LocaleListCompat localeListCompat = AppCompatDelegate.getApplicationLocales(); + int size = localeListCompat.size(); + KrollDict[] locales = new KrollDict[size]; + for (int i = 0; i < size; i++) { + Locale locale = localeListCompat.get(i); + if (locale != null) { + KrollDict localeObj = new KrollDict(); + localeObj.put("country", locale.getCountry()); + localeObj.put("iso3Country", locale.getISO3Country()); + localeObj.put("displayCountry", locale.getDisplayCountry()); + localeObj.put("language", locale.getLanguage()); + localeObj.put("iso3Language", locale.getISO3Language()); + localeObj.put("displayLanguage", locale.getDisplayLanguage()); + localeObj.put("variant", locale.getVariant()); + localeObj.put("displayVariant", locale.getDisplayVariant()); + localeObj.put("script", locale.getScript()); + localeObj.put("displayScript", locale.getDisplayScript()); + localeObj.put("displayName", locale.getDisplayName()); + localeObj.put("languageTag", locale.toLanguageTag()); + Character[] extensionKeys = new Character[locale.getExtensionKeys().size()]; + String[] extensions = new String[locale.getExtensionKeys().size()]; + Iterator extensionKeysSize = locale.getExtensionKeys().iterator(); + int l = 0; + while (extensionKeysSize.hasNext()) { + extensionKeys[l] = extensionKeysSize.next(); + extensions[l] = locale.getExtension(extensionKeys[l]); + l++; + } + localeObj.put("extension_keys", extensionKeys); + localeObj.put("extensions", extensions); + locales[i] = localeObj; + } else { + locales[i] = null; + } + } + return locales; + } + @Kroll.getProperty public String getCurrentLanguage() { @@ -79,10 +141,9 @@ public String getLocaleCurrencySymbol(String localeString) /** * Undocumented method used to implement the JavaScript Intl.getCanonicalLocales() static method. - * @param locales - * Can be a string or array of strings providing locale IDs to convert to canonical locale IDs. Can be null. - * @return - * Returns the given locale string IDs converted to "canonical" string IDs. Duplicate locales are removed. + * + * @param locales Can be a string or array of strings providing locale IDs to convert to canonical locale IDs. Can be null. + * @return Returns the given locale string IDs converted to "canonical" string IDs. Duplicate locales are removed. * Returns an empty array if given locales are invalid/unsupported or if given a null locales argument. */ @Kroll.method @@ -104,10 +165,10 @@ public String[] getCanonicalLocales(@Kroll.argument(optional = true) Object loca /** * Undocumented method used to implement the JavaScript Intl.Collator.supportedLocalesOf() static method. + * * @param locales Can be a string or array of strings providing the locale IDs to search for. Can be null. * @param options The Intl.Collator.supportedLocalesOf() argument. Currently ignored. - * @return - * Returns a subset of locale IDs from the given argument that are supported by the system. + * @return Returns a subset of locale IDs from the given argument that are supported by the system. * Returns an empty array if none of the locales are supported or if given a null locales argument. */ @Kroll.method @@ -120,10 +181,10 @@ public String[] getSupportedCollatorLocales(Object locales, @Kroll.argument(opti /** * Undocumented method used to implement the JavaScript Intl.DateTimeFormat.supportedLocalesOf() static method. + * * @param locales Can be a string or array of strings providing the locale IDs to search for. Can be null. * @param options The Intl.DateTimeFormat.supportedLocalesOf() argument. Currently ignored. - * @return - * Returns a subset of locale IDs from the given argument that are supported by the system. + * @return Returns a subset of locale IDs from the given argument that are supported by the system. * Returns an empty array if none of the locales are supported or if given a null locales argument. */ @Kroll.method @@ -136,10 +197,10 @@ public String[] getSupportedDateTimeFormatLocales(Object locales, @Kroll.argumen /** * Undocumented method used to implement the JavaScript Intl.NumberFormat.supportedLocalesOf() static method. + * * @param locales Can be a string or array of strings providing the locale IDs to search for. Can be null. * @param options The Intl.NumberFormat.supportedLocalesOf() argument. Currently ignored. - * @return - * Returns a subset of locale IDs from the given argument that are supported by the system. + * @return Returns a subset of locale IDs from the given argument that are supported by the system. * Returns an empty array if none of the locales are supported or if given a null locales argument. */ @Kroll.method diff --git a/android/templates/build/ti.constants.gradle b/android/templates/build/ti.constants.gradle index 6988acc5601..08f356ff73e 100644 --- a/android/templates/build/ti.constants.gradle +++ b/android/templates/build/ti.constants.gradle @@ -7,7 +7,7 @@ project.ext { tiNdkVersion = '26.2.11394342' - tiAndroidXAppCompatLibVersion = '1.4.1' + tiAndroidXAppCompatLibVersion = '1.6.0' tiAndroidXCoreLibVersion = '1.9.0' tiAndroidXFragmentLibVersion = '1.5.7' tiMaterialLibVersion = '1.6.1' diff --git a/apidoc/Titanium/Locale/Locale.yml b/apidoc/Titanium/Locale/Locale.yml index f59a62a8ad2..f66309782a9 100644 --- a/apidoc/Titanium/Locale/Locale.yml +++ b/apidoc/Titanium/Locale/Locale.yml @@ -235,3 +235,14 @@ properties: sections of wikipedia for reference. type: String permission: read-only + + - name: applicationLocales + summary: Update or retrieve Android's Per-app languages. + platforms: [android] + description: | + This property holds the values of Android's Per-app languages which is an array of defined Per-app languages, + if no languages defined, an empty array will be returned. You can set the value of it like this `en-US,en-GB,ar-SA`. + This property requires Android API level 33 and above. + See the [Android's Per-app languages](https://developer.android.com/guide/topics/resources/app-languages). + type: Array + since: "12.6.0"