Skip to content

Commit f064ba3

Browse files
Merge pull request #89 from shiv19/master
feat(LanguageSwitch): Added support to dynamically switch language on Android
2 parents 6766d37 + 7f6757e commit f064ba3

File tree

7 files changed

+129
-19
lines changed

7 files changed

+129
-19
lines changed

README.md

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,88 @@ Keys starting with `ios.info.plist.` are used to localize iOS properties:
178178
### How to change the language dynamically at runtime?
179179
This plugin uses the native capabilities of each platform, language selection is therefore made by the OS.
180180

181-
On iOS you can programmatically override this language since plugin version 4.2.0 by doing this:
181+
## On iOS you can programmatically override this language since plugin version 4.2.0 by doing this:
182182

183183
```typescript
184184
import { overrideLocale } from "nativescript-localize/localize";
185-
const localeOverriddenSuccessfully = overrideLocale("en-GB"); // or "nl-NL", etc
185+
const localeOverriddenSuccessfully = overrideLocale("en-GB"); // or "nl-NL", etc (or even just the part before the hyphen)
186+
```
187+
188+
## On Android you can programatically override this language since plugin version 4.2.1 by doing this:
189+
190+
In your app.ts / main.ts / app.js
191+
192+
```ts
193+
import { on, launchEvent } from '@nativescript/core/application';
194+
import { androidLaunchEventLocalizationHandler } from 'nativescript-localize/localize';
195+
196+
on(launchEvent, (args) => {
197+
if (args.android) {
198+
androidLaunchEventLocalizationHandler();
199+
}
200+
});
201+
```
202+
203+
And in your settings page where user chooses the language:
204+
205+
```ts
206+
import { overrideLocale } from "nativescript-localize/localize";
207+
const localeOverriddenSuccessfully = overrideLocale("en-GB"); // or "nl-NL", etc (or even just the part before the hyphen)
208+
```
209+
210+
> **Important:** In both cases, after calling override Locale, you must ask the user to restart the app
211+
212+
For Example:
213+
214+
```ts
215+
import { android as _android } from '@nativescript/core/application';
216+
import { overrideLocale } from 'nativescript-localize/localize';
217+
218+
alert({
219+
title: 'Switch Language',
220+
message: 'The application needs to be restarted to change language',
221+
okButtonText: 'Quit!'
222+
}).then(() => {
223+
L.localize.overrideLocale(selectedLang);
224+
if (isAndroid) {
225+
_android.foregroundActivity.finish();
226+
} else {
227+
exit(0);
228+
}
229+
});
230+
```
231+
232+
> **Important:** In case you are using [Android app bundle](https://docs.nativescript.org/tooling/publishing/android-app-bundle) to release your android app, add this to
233+
> App_Resources/Android/app.gradle to make sure all lanugages are bundled in the split apks
234+
235+
```groovy
236+
android {
237+
238+
// there maybe other code here //
239+
240+
bundle {
241+
language {
242+
enableSplit = false
243+
}
244+
}
245+
}
246+
```
247+
248+
> **Tip:** you can get the default language on user's phone by using this
249+
250+
```ts
251+
import { device } from '@nativescript/core/platform';
252+
253+
console.log("user's language is", device.language.split('-')[0]);
254+
```
255+
256+
> **Tip:** overrideLocale method stores the language in a special key in app-settings,
257+
> you can access it like this,
258+
259+
```ts
260+
import { getString } from '@nativescript/core/application-settings';
261+
262+
console.log(getString('__app__language__')); // only available after the first time you use overrideLocale(langName);
186263
```
187264

188265
## Troubleshooting

publish/package-lock.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { localize, overrideLocale } from "./localize";
1+
import { localize, overrideLocale, androidLaunchEventLocalizationHandler } from "./localize";
22

33
module.exports = localize;
44
module.exports.default = localize;
55
module.exports.localize = localize;
66
module.exports.overrideLocale = overrideLocale;
7+
module.exports.androidLaunchEventLocalizationHandler = androidLaunchEventLocalizationHandler;

src/localize.android.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import { vsprintf } from "sprintf-js";
2-
import * as utils from "utils/utils";
2+
import * as utils from "tns-core-modules/utils/utils";
3+
import { getString, setString } from 'tns-core-modules/application-settings';
4+
import { isAndroid } from 'tns-core-modules/platform';
5+
import { android as _android } from 'tns-core-modules/application';
36

47
import { encodeKey } from "./resource";
58

9+
declare var java: any;
10+
611
const getResources = (function () {
712
let resources = null;
813
return function () {
@@ -24,7 +29,22 @@ export function localize(key: string, ...args: string[]): string {
2429
return vsprintf(localizedString, args);
2530
}
2631

32+
export function androidLaunchEventLocalizationHandler() {
33+
const lang = getString('__app__language__', 'none');
34+
if (lang !== 'none' && isAndroid) {
35+
const locale = new java.util.Locale(lang);
36+
java.util.Locale.setDefault(locale);
37+
38+
const resources = _android.context.getResources();
39+
const configuration = resources.getConfiguration();
40+
configuration.locale = locale;
41+
42+
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
43+
}
44+
}
45+
2746
export function overrideLocale(locale: string): boolean {
28-
console.log("overrideLocale is not (yet) implemented on Android");
29-
return false;
47+
setString('__app__language__', locale.substring(0, 2));
48+
49+
return true;
3050
}

src/localize.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export declare function localize(key: string, ...args: string[]): string;
22
export declare function overrideLocale(locale: string): boolean;
3+
export declare function androidLaunchEventLocalizationHandler(): void;

src/localize.ios.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { vsprintf } from "sprintf-js";
22

33
import { convertAtSignToStringSign } from "./placeholder";
44
import { encodeKey } from "./resource";
5+
import { setString } from "tns-core-modules/application-settings";
56

67
let bundle;
78

@@ -19,6 +20,10 @@ export function localize(key: string, ...args: string[]): string {
1920
return vsprintf(convertAtSignToStringSign(localizedString), args);
2021
}
2122

23+
export function androidLaunchEventLocalizationHandler() {
24+
// dummy
25+
}
26+
2227
export function overrideLocale(locale: string): boolean {
2328
const path = NSBundle.mainBundle.pathForResourceOfType(locale.substring(0, 2), "lproj");
2429

@@ -29,5 +34,7 @@ export function overrideLocale(locale: string): boolean {
2934
bundle = NSBundle.bundleWithPath(path);
3035
NSUserDefaults.standardUserDefaults.setObjectForKey([locale], "AppleLanguages");
3136
NSUserDefaults.standardUserDefaults.synchronize();
37+
setString('__app__language__', locale.substring(0, 2));
38+
3239
return true;
3340
}

src/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "nativescript-localize",
33
"description": "Native internationalization plugin for NativeScript using native capabilities of each platform",
4-
"version": "4.2.0",
4+
"version": "4.2.1",
55
"keywords": [
66
"nativescript",
77
"internationalization",
@@ -28,6 +28,10 @@
2828
{
2929
"name": "Brendan Ingham",
3030
"email": "[email protected]"
31+
},
32+
{
33+
"name": "MultiShiv19",
34+
"email": "[email protected]"
3135
}
3236
],
3337
"main": "index.js",

0 commit comments

Comments
 (0)