Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: Language on iOS/Android


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 3 - Last Post: Jun 17, 2016 3:41 AM Last Post By: Chris Pimlott Threads: [ Previous | Next ]
Andre Wiget

Posts: 20
Registered: 2/28/03
Language on iOS/Android  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 5, 2015 1:05 AM
Hi,

I try to get the language on iOS and Android devices.

I use the following code:
if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService, IInterface(LocServ)) then
Result := LocServ.GetCurrentLangID;

The problem is that I only get 'de' for german. But there is a difference between german in Germany and german in Switzerland. So I need 'de_DE' or 'de_CH'. How can I do that ?

Thanks in advance for every hint.

Andre
Remy Lebeau (Te...


Posts: 9,448
Registered: 12/23/01
Re: Language on iOS/Android  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 5, 2015 11:38 AM   in response to: Andre Wiget in response to: Andre Wiget
Andre wrote:

I use the following code:
if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService,
IInterface(LocServ)) then
Result := LocServ.GetCurrentLangID;
The problem is that I only get 'de' for german.

On Android, IFMXLocaleService.GetCurrentLangID() calls Android's Locale.getDefault()
static method to get a Locale object, then calls its getISO3Language() method,
which returns a 3-letter ISO 639-2/T formatted language name, such as "deu"
for German (swiss German is "gsw" instead - see http://www.loc.gov/standards/iso639-2/php/code_list.php).

On iOS, IFMXLocaleService.GetCurrentLangID() calls iOS's NSLocale.currentLocale()
static method to get an NSLocale object, then calls its objectForKey() method
requesting the NSLocaleLanguageCode key, which returns a 2-character language
code, like "de".

In both cases, Delphi deletes everything after the second character, if present
(thus "deu" becomes "de").

But there is a difference between german in Germany and german in
Switzerland. So I need 'de_DE' or 'de_CH'. How can I do that ?

Android and iOS do not provide such strings. Both Android and iOS separate
language codes from country codes, and FireMonkey does not expose any access
to country codes (that I can see). Fortunately, Android's Locale class does
have getCountry() and getISO3Country() methods, and iOS's NSLocale.objectForKey()
method does have a NSLocaleCountryCode key, so you can use Delphi's Android/iOS
Bridge frameworks to access the native classes directly.

--
Remy Lebeau (TeamB)
Andre Wiget

Posts: 20
Registered: 2/28/03
Re: Language on iOS/Android  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2015 9:52 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Andre wrote:

I use the following code:
if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService,
IInterface(LocServ)) then
Result := LocServ.GetCurrentLangID;
The problem is that I only get 'de' for german.

On Android, IFMXLocaleService.GetCurrentLangID() calls Android's Locale.getDefault()
static method to get a Locale object, then calls its getISO3Language() method,
which returns a 3-letter ISO 639-2/T formatted language name, such as "deu"
for German (swiss German is "gsw" instead - see http://www.loc.gov/standards/iso639-2/php/code_list.php).

On iOS, IFMXLocaleService.GetCurrentLangID() calls iOS's NSLocale.currentLocale()
static method to get an NSLocale object, then calls its objectForKey() method
requesting the NSLocaleLanguageCode key, which returns a 2-character language
code, like "de".

In both cases, Delphi deletes everything after the second character, if present
(thus "deu" becomes "de").

But there is a difference between german in Germany and german in
Switzerland. So I need 'de_DE' or 'de_CH'. How can I do that ?

Android and iOS do not provide such strings. Both Android and iOS separate
language codes from country codes, and FireMonkey does not expose any access
to country codes (that I can see). Fortunately, Android's Locale class does
have getCountry() and getISO3Country() methods, and iOS's NSLocale.objectForKey()
method does have a NSLocaleCountryCode key, so you can use Delphi's Android/iOS
Bridge frameworks to access the native classes directly.

--
Remy Lebeau (TeamB)

Thank you very much. I'll try to use the Bridge framework.

Andre
Chris Pimlott

Posts: 4
Registered: 1/14/15
Re: Language on iOS/Android  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 17, 2016 3:41 AM   in response to: Andre Wiget in response to: Andre Wiget
Hi Andre

Thanks for everyone in this thread - it helped me find a solution using the native APIs. As I wrote a self-contained function for this, I thought it would be useful to share for anyone else who might need it:

uses
{$IFDEF IOS}
iOSAPI.Foundation, MacAPI.ObjectiveC,
{$ENDIF}
{$IFDEF ANDROID}
AndroidAPI.JNI.JavaTypes, AndroidApi.Helpers,
{$ENDIF}

function GetDeviceCountry: String;
{$IFDEF ANDROID}
var
Locale: JLocale;
{$ENDIF}
{$IFDEF IOS}
const
FoundationFwk: string = '/System/Library/Frameworks/Foundation.framework/Foundation';
var
CurrentLocale: NSLocale;
CountryISO: NSString;
{$ENDIF}
begin
Result:='Unknown';
{$IFDEF ANDROID}
Locale := TJLocale.JavaClass.getDefault;
Result := JStringToString(Locale.getISO3Country);
{$ENDIF}
{$IFDEF IOS}
CurrentLocale := TNSLocale.Wrap(TNSLocale.OCClass.currentLocale);
CountryISO := TNSString.Wrap(CurrentLocale.objectForKey((CocoaNSStringConst(FoundationFwk, 'NSLocaleCountryCode') as ILocalObject).GetObjectID));
Result := UTF8ToString(CountryISO.UTF8String);
{$ENDIF}
if Length(Result) > 2 then
Delete(Result, 3, MaxInt);
end;

Maybe not the cleanest code, but hopefully it'll help

Chris
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02