New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add method to obtain native string resource in localization plugin. #24575
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,12 @@ | |
|
||
import android.content.Context; | ||
import android.content.res.Configuration; | ||
import android.content.res.Resources; | ||
import android.os.Build; | ||
import android.os.LocaleList; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.VisibleForTesting; | ||
import io.flutter.embedding.engine.systemchannels.LocalizationChannel; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
@@ -19,11 +22,56 @@ public class LocalizationPlugin { | |
@NonNull private final LocalizationChannel localizationChannel; | ||
@NonNull private final Context context; | ||
|
||
@VisibleForTesting | ||
final LocalizationChannel.LocalizationMessageHandler localizationMessageHandler = | ||
new LocalizationChannel.LocalizationMessageHandler() { | ||
@Override | ||
public String getStringResource(@NonNull String key, @Nullable String localeString) { | ||
Context localContext = context; | ||
String stringToReturn = null; | ||
Locale savedLocale = null; | ||
|
||
if (localeString != null) { | ||
Locale locale = localeFromString(localeString); | ||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, comment the API number for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
Configuration conf = new Configuration(context.getResources().getConfiguration()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, spell out There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. I went with |
||
conf.setLocale(locale); | ||
localContext = context.createConfigurationContext(conf); | ||
} else { | ||
// setLocale and createConfigurationContext is only available on API >= 17 | ||
Resources resources = context.getResources(); | ||
Configuration conf = resources.getConfiguration(); | ||
savedLocale = conf.locale; | ||
conf.locale = locale; | ||
resources.updateConfiguration(conf, null); | ||
} | ||
} | ||
|
||
String packageName = context.getPackageName(); | ||
int resId = localContext.getResources().getIdentifier(key, "string", packageName); | ||
if (resId != 0) { | ||
// 0 means the resource is not found. | ||
stringToReturn = localContext.getResources().getString(resId); | ||
} | ||
|
||
if (localeString != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, comment the API number for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
Resources resources = context.getResources(); | ||
Configuration conf = resources.getConfiguration(); | ||
conf.locale = savedLocale; | ||
resources.updateConfiguration(conf, null); | ||
} | ||
|
||
return stringToReturn; | ||
} | ||
}; | ||
|
||
public LocalizationPlugin( | ||
@NonNull Context context, @NonNull LocalizationChannel localizationChannel) { | ||
|
||
this.context = context; | ||
this.localizationChannel = localizationChannel; | ||
this.localizationChannel.setLocalizationMessageHandler(localizationMessageHandler); | ||
} | ||
|
||
/** | ||
|
@@ -136,4 +184,39 @@ public void sendLocalesToFlutter(@NonNull Configuration config) { | |
|
||
localizationChannel.sendLocales(locales); | ||
} | ||
|
||
@VisibleForTesting | ||
public static Locale localeFromString(String localeString) { | ||
GaryQian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Use Locale.forLanguageTag if available (API 21+). | ||
if (false && Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any chance you remember why this if block exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most likely a mistake. The Do you want me to send a PR to undo this? |
||
return Locale.forLanguageTag(localeString); | ||
} else { | ||
// Normalize the locale string, replace all underscores with hyphens. | ||
localeString = localeString.replace('_', '-'); | ||
|
||
// Pre-API 21, we fall back to manually parsing the locale tag. | ||
String parts[] = localeString.split("-", -1); | ||
|
||
// The format is: | ||
// language[-script][-region][-...] | ||
// where script is an alphabet string of length 4, and region is either an alphabet string of | ||
// length 2 or a digit string of length 3. | ||
|
||
// Assume the first part is always the language code. | ||
String languageCode = parts[0]; | ||
String scriptCode = ""; | ||
String countryCode = ""; | ||
int index = 1; | ||
if (parts.length > index && parts[index].length() == 4) { | ||
scriptCode = parts[index]; | ||
index++; | ||
} | ||
if (parts.length > index && parts[index].length() >= 2 && parts[index].length() <= 3) { | ||
countryCode = parts[index]; | ||
index++; | ||
} | ||
// Ignore the rest of the locale for this purpose. | ||
return new Locale(languageCode, countryCode, scriptCode); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rephrase to be less passive/third person.
perhaps
Obtains the string resource of the provided {@code key} ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied the tone from
PlatformChannel.java
.The way I understand it is this comment is meant for the implementor of this interface.
What do you think?