-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathomNativeLanguage.pas
123 lines (100 loc) · 3.7 KB
/
omNativeLanguage.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
unit omNativeLanguage; // by oMAR may20
// Cross platdform native language OS setting (Windows, iOS and Android) TODO: MacOS
interface
var // NativeLanguage is set at initialization
NativeLanguage:String=''; // like 'pt-BR' ou 'en-US'
implementation //-----------------------------------------------------
uses
{$IFDEF Android}
FMX.Platform, //Om: plat services
Androidapi.JNIBridge,
Androidapi.Helpers,
Androidapi.JNI.JavaTypes;
{$ENDIF Android}
{$IFDEF IOS}
iOSapi.Foundation,
iOSapi.AVFoundation,
Macapi.Helpers;
{$ENDIF IOS}
{$IFDEF MSWINDOWS}
Winapi.Windows;
{$ENDIF MSWINDOWS}
// Android ---------------------------------------------------------
{$IFDEF Android}
function getDeviceCountryCode:String; //platform specific get country code
var Locale: JLocale;
begin
Result:='??';
Locale := TJLocale.JavaClass.getDefault;
Result := JStringToString( Locale.getCountry );
if Length(Result) > 2 then Delete(Result, 3, MaxInt);
end;
function getOSLanguage:String;
var LocServ: IFMXLocaleService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService, IInterface(LocServ)) then
Result := LocServ.GetCurrentLangID // 2 letter code, but a different one ???? instead of 'pt' it gives 'po'
else Result := '??';
// if set Japanese on Android, LocaleService returns "jp", but other platform returns "ja"
// so I think it is better to change "jp" to "ja"
if (Result = 'jp') then Result := 'ja'
else if (Result = 'po') then Result := 'pt';
end;
procedure getNativeLanguage; // Android
begin
NativeLanguage := getOSLanguage+'-'+getDeviceCountryCode; // 'pt-BR'
end;
{$ENDIF Android}
// iOS--------------------------------------------------------------
{$IFDEF IOS}
function getOSLanguage:String; //default language 'es-ES' 'en-US' 'pt-BR' ..
var
Languages: NSArray;
begin
Languages := TNSLocale.OCClass.preferredLanguages;
Result := TNSString.Wrap(Languages.objectAtIndex(0)).UTF8String;
end;
procedure getNativeLanguage;
begin
NativeLanguage := getOSLanguage; // 'pt-BR'
end;
{$ENDIF IOS}
// Windows -------------------------------------------
{$IFDEF MSWINDOWS}
// from https://stackoverflow.com/questions/19369809/delphi-get-country-codes-by-localeid/37981772#37981772
function LCIDToLocaleName(Locale: LCID; lpName: LPWSTR; cchName: Integer;
dwFlags: DWORD): Integer; stdcall;external kernel32 name 'LCIDToLocaleName';
function LocaleIDString():string;
var
strNameBuffer : array [0..255] of WideChar; // 84 was len from original process online
//localID : TLocaleID;
// localID was 0, so didn't initialize, but still returned proper code page.
// using 0 in lieu of localID : nets the same result, var not required.
i : integer;
begin
Result := '';
// LOCALE_USER_DEFAULT vs. LOCALE_SYSTEM_DEFAULT
// since XP LOCALE_USER_DEFAULT is considered good practice for compatibility
if (LCIDToLocaleName(LOCALE_USER_DEFAULT, strNameBuffer, 255, 0) > 0) then
for i := 0 to 255 do
begin
if strNameBuffer[i] = #0 then break
else Result := Result + strNameBuffer[i];
end;
if (Length(Result) = 0) and (LCIDToLocaleName(0, strNameBuffer, 255, 0) > 0) then
for i := 0 to 255 do
begin
if strNameBuffer[i] = #0 then break
else Result := Result + strNameBuffer[i];
end;
if Length(Result) = 0 then
Result := 'NR-NR' // defaulting to [No Reply - No Reply]
end;
procedure getNativeLanguage;
begin
NativeLanguage := LocaleIDString; // 'pt-BR'
end;
{$ENDIF MSWINDOWS}
initialization
getNativeLanguage; // get OS native language-country
end.