using System.Globalization; using System.Threading; using Gallery.Resources; #if __IOS__ using System.Diagnostics.CodeAnalysis; using Foundation; using UIKit; #elif __ANDROID__ using Android.OS; using Xamarin.Forms.Platform.Android; #endif using Xamarin.Forms; namespace Gallery.Utils { public class EnvironmentService { #region - Theme - /* [SuppressMessage("Code Notifications", "XI0002:Notifies you from using newer Apple APIs when targeting an older OS version", Justification = "")] public AppTheme GetApplicationTheme() { if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0)) { var currentController = Platform.GetCurrentUIViewController(); if (currentController == null) { return AppTheme.Unspecified; } var style = currentController.TraitCollection.UserInterfaceStyle; if (style == UIUserInterfaceStyle.Dark) { return AppTheme.Dark; } else if (style == UIUserInterfaceStyle.Light) { return AppTheme.Light; } } return AppTheme.Unspecified; } //*/ public static void SetStatusBarColor(Color color) { #if __ANDROID_21__ if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) { Droid.MainActivity.Main.SetStatusBarColor(color.ToAndroid()); Droid.MainActivity.Main.Window.DecorView.SystemUiVisibility = App.CurrentTheme == Xamarin.Essentials.AppTheme.Dark ? Android.Views.StatusBarVisibility.Visible : (Android.Views.StatusBarVisibility)Android.Views.SystemUiFlags.LightStatusBar; } #endif } public static void SetStatusBarStyle(StatusBarStyles style) { #if __IOS__ SetStatusBarStyle(ConvertStyle(style)); } public static void SetStatusBarStyle(UIStatusBarStyle style) { if (UIApplication.SharedApplication.StatusBarStyle == style) { return; } if (style == UIStatusBarStyle.BlackOpaque) { UIApplication.SharedApplication.SetStatusBarHidden(true, true); } else { UIApplication.SharedApplication.SetStatusBarStyle(style, true); UIApplication.SharedApplication.SetStatusBarHidden(false, true); } } [SuppressMessage("Code Notifications", "XI0002:Notifies you from using newer Apple APIs when targeting an older OS version", Justification = "")] public static UIStatusBarStyle ConvertStyle(StatusBarStyles style) { switch (style) { case StatusBarStyles.DarkText: return UIStatusBarStyle.DarkContent; case StatusBarStyles.WhiteText: return UIStatusBarStyle.LightContent; case StatusBarStyles.Hidden: return UIStatusBarStyle.BlackOpaque; case StatusBarStyles.Default: default: return UIStatusBarStyle.Default; } } #else } #endif #endregion #region - Culture Info - public static void SetCultureInfo(CultureInfo ci) { Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentUICulture = ci; #if LOG App.DebugPrint($"CurrentCulture set: {ci.Name}"); #endif } public static CultureInfo GetCurrentCultureInfo() { string lang; #if __IOS__ if (NSLocale.PreferredLanguages.Length > 0) { var pref = NSLocale.PreferredLanguages[0]; lang = iOSToDotnetLanguage(pref); } else { lang = "zh-CN"; } #elif __ANDROID__ var locale = Java.Util.Locale.Default; lang = AndroidToDotnetLanguage(locale.ToString().Replace('_', '-')); #endif CultureInfo ci; var platform = new PlatformCulture(lang); try { ci = new CultureInfo(platform.Language); } catch (CultureNotFoundException e) { try { var fallback = ToDotnetFallbackLanguage(platform); App.DebugPrint($"{lang} failed, trying {fallback} ({e.Message})"); ci = new CultureInfo(fallback); } catch (CultureNotFoundException e1) { App.DebugError("culture.get", $"{lang} couldn't be set, using 'zh-CN' ({e1.Message})"); ci = new CultureInfo("zh-CN"); } } return ci; } #if __IOS__ [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "")] private static string iOSToDotnetLanguage(string iOSLanguage) { string netLanguage; //certain languages need to be converted to CultureInfo equivalent switch (iOSLanguage) { case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture netLanguage = "ms"; // closest supported 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 default: netLanguage = iOSLanguage; break; } #if DEBUG App.DebugPrint($"iOS Language: {iOSLanguage}, .NET Language/Locale: {netLanguage}"); #endif return netLanguage; } #elif __ANDROID__ private static string AndroidToDotnetLanguage(string androidLanguage) { string netLanguage; //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 default: netLanguage = androidLanguage; break; } #if DEBUG App.DebugPrint($"Android Language: {androidLanguage}, .NET Language/Locale: {netLanguage}"); #endif return netLanguage; } #endif private static string ToDotnetFallbackLanguage(PlatformCulture platCulture) { string netLanguage; switch (platCulture.LanguageCode) { // case "pt": netLanguage = "pt-PT"; // fallback to Portuguese (Portugal) break; 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 default: netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually); break; } #if DEBUG App.DebugPrint($".NET Fallback Language/Locale: {platCulture.LanguageCode} to {netLanguage} (application-specific)"); #endif return netLanguage; } #endregion } }