From e58956d392d0be7808bd64fee238e0954994badc Mon Sep 17 00:00:00 2001 From: Rouddy Date: Tue, 4 Jun 2024 14:40:31 +0900 Subject: [PATCH] Resolved issue where "NewApi" build error occurred in API version 21 or lower. --- android/build.gradle | 2 + .../country_codes/CountryCodesPlugin.kt | 65 ++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index ab14ed1..3a3dd33 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -49,4 +49,6 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + + implementation 'org.apache.commons:commons-lang3:3.6' } diff --git a/android/src/main/kotlin/com/miguelruivo/flutter/plugin/countrycodes/country_codes/CountryCodesPlugin.kt b/android/src/main/kotlin/com/miguelruivo/flutter/plugin/countrycodes/country_codes/CountryCodesPlugin.kt index 98b248c..a75773d 100644 --- a/android/src/main/kotlin/com/miguelruivo/flutter/plugin/countrycodes/country_codes/CountryCodesPlugin.kt +++ b/android/src/main/kotlin/com/miguelruivo/flutter/plugin/countrycodes/country_codes/CountryCodesPlugin.kt @@ -1,6 +1,7 @@ package com.miguelruivo.flutter.plugin.countrycodes.country_codes import android.R +import android.os.Build import java.util.Locale import androidx.annotation.NonNull; import io.flutter.embedding.engine.plugins.FlutterPlugin @@ -9,6 +10,7 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.PluginRegistry.Registrar +import org.apache.commons.lang3.LocaleUtils /** CountryCodesPlugin */ public class CountryCodesPlugin: FlutterPlugin, MethodCallHandler { @@ -47,11 +49,11 @@ public class CountryCodesPlugin: FlutterPlugin, MethodCallHandler { private fun getLocalizedCountryNames(localeTag: String?) : HashMap { var localizedCountries: HashMap = HashMap() - val deviceCountry: String = Locale.getDefault().toLanguageTag(); + val deviceCountry: String = Locale.getDefault().getLanguageTag(); for (countryCode in Locale.getISOCountries()) { val locale = Locale(localeTag ?: deviceCountry,countryCode) - var countryName: String? = locale.getDisplayCountry(Locale.forLanguageTag(localeTag ?: deviceCountry)) + var countryName: String? = locale.getDisplayCountry(initLocaleForTag(localeTag ?: deviceCountry)) localizedCountries[countryCode.toUpperCase()] = countryName ?: ""; } return localizedCountries @@ -59,4 +61,63 @@ public class CountryCodesPlugin: FlutterPlugin, MethodCallHandler { override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { } + + private fun initLocaleForTag(languageTag: String): Locale { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return Locale.forLanguageTag(languageTag) + } + + return LocaleUtils.toLocale(languageTag) + } +} + +private fun Locale.getLanguageTag(): String { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return toLanguageTag() + } + + // we will use a dash as per BCP 47 + val SEP = '-' + var language: String = language + var region: String = country + var variant: String = variant + + // special case for Norwegian Nynorsk since "NY" cannot be a variant as per BCP 47 + // this goes before the string matching since "NY" wont pass the variant checks + if (language == "no" && region == "NO" && variant == "NY") { + language = "nn" + region = "NO" + variant = "" + } + + if (language.isEmpty() || !language.matches(Regex("\\p{Alpha}{2,8}"))) { + language = "und" // Follow the Locale#toLanguageTag() implementation + // which says to return "und" for Undetermined + } else if (language.equals("iw")) { + language = "he" // correct deprecated "Hebrew" + } else if (language.equals("in")) { + language = "id" // correct deprecated "Indonesian" + } else if (language.equals("ji")) { + language = "yi" // correct deprecated "Yiddish" + } + + // ensure valid country code, if not well formed, it's omitted + if (!region.matches(Regex("\\p{Alpha}{2}|\\p{Digit}{3}"))) { + region = "" + } + + // variant subtags that begin with a letter must be at least 5 characters long + if (!variant.matches(Regex("\\p{Alnum}{5,8}|\\p{Digit}\\p{Alnum}{3}"))) { + variant = "" + } + + val bcp47Tag = StringBuilder(language) + if (region.isNotEmpty()) { + bcp47Tag.append(SEP).append(region) + } + if (variant.isNotEmpty()) { + bcp47Tag.append(SEP).append(variant) + } + + return bcp47Tag.toString() }