Bug 56026 - Localization doesn't work using "Bundle Assemblies into Native Code" in release mode
Summary: Localization doesn't work using "Bundle Assemblies into Native Code" in relea...
Status: RESOLVED DUPLICATE of bug 55603
Alias: None
Product: Android
Classification: Xamarin
Component: General (show other bugs)
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2017-05-05 10:03 UTC by batmaci
Modified: 2017-05-05 15:47 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
android configuration screenshot (27.24 KB, image/png)
2017-05-05 10:03 UTC, batmaci
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED DUPLICATE of bug 55603

Description batmaci 2017-05-05 10:03:05 UTC
Created attachment 21970 [details]
android configuration screenshot

I followed the https://developer.xamarin.com/guides/xamarin-forms/advanced/localization/ and using resx files with displaying correct language, with DI on Android, I am able to change language within my app. 
Basically in Android, I added platform specific code as described in the article

    `[assembly:Dependency(typeof(UsingResxLocalization.Android.Localize))]
    
    namespace UsingResxLocalization.Android
    {
        public class Localize : UsingResxLocalization.ILocalize
        {
            public void SetLocale(CultureInfo ci)
            {
                Thread.CurrentThread.CurrentCulture = ci;
                Thread.CurrentThread.CurrentUICulture = ci;
            }
            public CultureInfo GetCurrentCultureInfo()
            {
                var netLanguage = "en";
                var androidLocale = Java.Util.Locale.Default;
                netLanguage = AndroidToDotnetLanguage(androidLocale.ToString().Replace("_", "-"));
                // this gets called a lot - try/catch can be expensive so consider caching or something
                System.Globalization.CultureInfo ci = null;
                try
                {
                    ci = new System.Globalization.CultureInfo(netLanguage);
                }
                catch (CultureNotFoundException e1)
                {
                    // iOS locale not valid .NET culture (eg. "en-ES" : English in Spain)
                    // fallback to first characters, in this case "en"
                    try
                    {
                        var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
                        ci = new System.Globalization.CultureInfo(fallback);
                    }
                    catch (CultureNotFoundException e2)
                    {
                        // iOS language not valid .NET culture, falling back to English
                        ci = new System.Globalization.CultureInfo("en");
                    }
                }
                return ci;
            }
            string AndroidToDotnetLanguage(string androidLanguage)
            {
                var netLanguage = androidLanguage;
                //certain languages need to be converted to CultureInfo equivalent
                switch (androidLanguage)
                {
                    case "ms-BN":   // "Malaysian (Brunei)" not supported .NET culture
                    case "ms-MY":   // "Malaysian (Malaysia)" not supported .NET culture
                    case "ms-SG":   // "Malaysian (Singapore)" not supported .NET culture
                        netLanguage = "ms"; // closest supported
                        break;
                    case "in-ID":  // "Indonesian (Indonesia)" has different code in  .NET
                        netLanguage = "id-ID"; // correct code for .NET
                        break;
                    case "gsw-CH":  // "Schwiizertüütsch (Swiss German)" not supported .NET culture
                        netLanguage = "de-CH"; // closest supported
                        break;
                        // add more application-specific cases here (if required)
                        // ONLY use cultures that have been tested and known to work
                }
                return netLanguage;
            }
            string ToDotnetFallbackLanguage(PlatformCulture platCulture)
            {
                var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
                switch (platCulture.LanguageCode)
                {
                    case "gsw":
                        netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app
                        break;
                        // add more application-specific cases here (if required)
                        // ONLY use cultures that have been tested and known to work
                }
                return netLanguage;
            }
        }
    }`

In PCL code I have 

 

    namespace myApp.Resx
    {
    
        /// <summary>
        /// Implementations of this interface MUST convert iOS and Android
        /// platform-specific locales to a value supported in .NET because
        /// ONLY valid .NET cultures can have their RESX resources loaded and used.
        /// </summary>
        /// <remarks>
        /// Lists of valid .NET cultures can be found here:
        ///   http://www.localeplanet.com/dotnet/
        ///   http://www.csharp-examples.net/culture-names/
        /// You should always test all the locales implemented in your application.
        /// </remarks>
        public interface ILocalize
        {
            ///	<summary>
            /// This method must evaluate platform-specific locale settings
            /// and convert them (when necessary) to a valid .NET locale.
            /// </summary>
            CultureInfo GetCurrentCultureInfo();
    
            /// <summary>
            /// CurrentCulture and CurrentUICulture must be set in the platform project, 
            /// because the Thread object can't be accessed in a PCL.
            /// </summary>
            void SetLocale(CultureInfo ci);
        }
    
        /// <summary>
        /// Helper class for splitting locales like
        ///   iOS: ms_MY, gsw_CH
        ///   Android: in-ID
        /// into parts so we can create a .NET culture (or fallback culture)
        /// </summary>
        public class PlatformCulture
        {
            public PlatformCulture(string platformCultureString)
            {
                if (String.IsNullOrEmpty(platformCultureString))
                    throw new ArgumentException("Expected culture identifier", "platformCultureString"); // in C# 6 use nameof(platformCultureString)
    
                PlatformString = platformCultureString.Replace("_", "-"); // .NET expects dash, not underscore
                var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal);
                if (dashIndex > 0)
                {
                    var parts = PlatformString.Split('-');
                    LanguageCode = parts[0];
                    LocaleCode = parts[1];
                }
                else
                {
                    LanguageCode = PlatformString;
                    LocaleCode = "";
                }
            }
            public string PlatformString { get; private set; }
            public string LanguageCode { get; private set; }
            public string LocaleCode { get; private set; }
            public override string ToString()
            {
                return PlatformString;
            }
        }
    }

then in my PCL code, I am able to overwrite the culture with the code below

      string name = Helpers.Settings.PreferredLanguage == "en" ? "en-US" : Helpers.Settings.PreferredLanguage + "-" + Helpers.Settings.PreferredLanguage.ToUpper();
                            currentCultureInfo = new System.Globalization.CultureInfo(name);
                            Xamarin.Forms.DependencyService.Get<Resx.ILocalize>().SetLocale(currentCultureInfo);                      
     
                    Resx.AppRes.Culture = currentCultureInfo;

This Code implementation works fine when I run in Debug and Release Mode.
But It fails working in Release Mode using "Bundle Assemblies into Native Code". 
when I enable, "Enable developer instrumentation" in Release mode, It works also.
If I remove the check for this option, It works fine.

What could be the possible problem? I dont know how to track this down. I tried using Android Device Monitor but it doesnt display much for it. 

configuration looks like as attached image. 

I haven't tried but I am guessing that you will have same problem using localization sample in the documentation. because I have just copied code from there without changing it.
Comment 1 Brendan Zagaeski (Xamarin Team, assistant) 2017-05-05 15:47:12 UTC

*** This bug has been marked as a duplicate of bug 55603 ***