{"id":13428699,"url":"https://github.com/akexorcist/Localization","last_synced_at":"2025-03-16T01:32:55.762Z","repository":{"id":35220959,"uuid":"39480138","full_name":"akexorcist/Localization","owner":"akexorcist","description":"[Android] In-app language changing library","archived":true,"fork":false,"pushed_at":"2022-06-21T21:04:23.000Z","size":2600,"stargazers_count":982,"open_issues_count":17,"forks_count":156,"subscribers_count":30,"default_branch":"master","last_synced_at":"2024-10-27T05:37:13.189Z","etag":null,"topics":["android","android-library","java","kotlin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akexorcist.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-22T02:07:12.000Z","updated_at":"2024-09-19T05:44:52.000Z","dependencies_parsed_at":"2022-08-24T01:41:21.505Z","dependency_job_id":null,"html_url":"https://github.com/akexorcist/Localization","commit_stats":null,"previous_names":["akexorcist/android-localization","akexorcist/android-localizationactivity"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akexorcist%2FLocalization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akexorcist%2FLocalization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akexorcist%2FLocalization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akexorcist%2FLocalization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akexorcist","download_url":"https://codeload.github.com/akexorcist/Localization/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243814905,"owners_count":20352037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","java","kotlin"],"created_at":"2024-07-31T01:01:03.101Z","updated_at":"2025-03-16T01:32:55.308Z","avatar_url":"https://github.com/akexorcist.png","language":"Kotlin","readme":"[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Android--Localization-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/2890)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.akexorcist/localization/badge.svg)](https://search.maven.org/artifact/com.akexorcist/localization) \n![Minimum SDK Version](https://img.shields.io/badge/minSdkVersion-14-brightgreen) \n[![Workflow Status](https://github.com/akexorcist/Android-Localization/actions/workflows/android.yml/badge.svg)](https://github.com/akexorcist/Localization/actions)\n\nDiscontinued\n====\nSince Google announced Android 13 with per-app language preferences supports. This feature also backport to older Android version with AndroidX. So there's no reason to contribute this library anymore. For more stability, compatibility, and longer supports from Google team, please migrate to AndroidX. See [Migrate to AndroidX guide](./MIGRATE_TO_ANDROIDX.md). \n\nLocalization Library\n====\n![Header image](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/01-header.jpg)\nAndroid library for in-app language changes support in your application \n\n\nFeature\n====\n* In-app language changing\n* Default language when first launch\n* Work with string resource in XML and programmatically\n* RTL language support\n* Align on platform behavior\n\n\nDemo\n====\nTry it at [Google Play](https://play.google.com/store/apps/details?id=com.akexorcist.localizationapp)\n\n\nDownload\n====\nSince version 1.2.9 will [move from JCenter to MavenCentral](https://developer.android.com/studio/build/jcenter-migration)\n\n```groovy\n// build.gradle (project)\nallprojects {\n    repositories {\n        mavenCentral()\n        /* ... */\n    }\n}\n```\n\nGradle\n```groovy\nimplementation 'com.akexorcist:localization:1.2.11'\n```\n\n(Optional) You can exclude `androidx.appcompat:appcompat`, if your project does not use AppCompat.\n```groovy\nimplementation ('com.akexorcist:localization:1.2.11') {\n    exclude group: 'androidx.core', module: 'core'\n}\n```\n\n\nUsage\n====\nCustom application class which extends from `LocalizationApplication` is require.\n```kotlin\nclass MainApplication: LocalizationApplication() {\n    /* ... */\n    override fun getDefaultLanguage(context: Context) = Locale.ENGLISH\n}\n```\n\nEither not, using `LocalizationApplicationDelegate` with additional code as below\n```kotlin\nclass MainApplication: Application() {\n    private val localizationDelegate = LocalizationApplicationDelegate()\n    \n    override fun attachBaseContext(base: Context) {\n        localizationDelegate.setDefaultLanguage(base, Locale.ENGLISH)\n        super.attachBaseContext(localizationDelegate.attachBaseContext(base))\n    }\n    \n    override fun onConfigurationChanged(newConfig: Configuration) {\n        super.onConfigurationChanged(newConfig)\n        localizationDelegate.onConfigurationChanged(this)\n    }\n    \n    override fun getApplicationContext(): Context {\n        return localizationDelegate.getApplicationContext(super.getApplicationContext())\n    }\n    \n    override fun getResources(): Resources {\n        return localizationDelegate.getResources(baseContext, super.getResources())\n    }\n}\n```\n\nFor the activities, extends from `LocalizationActivity`.\n\n```kotlin\nclass MainActivity: LocalizationActivity() {\n    /* ... */\n}\n``` \n\nOr using `LocalizationActivityDelegate` with additional code\n```kotlin\nopen class CustomActivity : Activity(), OnLocaleChangedListener {\n    private val localizationDelegate = LocalizationActivityDelegate(this)\n\n    public override fun onCreate(savedInstanceState: Bundle?) {\n        localizationDelegate.addOnLocaleChangedListener(this)\n        localizationDelegate.onCreate()\n        super.onCreate(savedInstanceState)\n    }\n\n    public override fun onResume() {\n        super.onResume()\n        localizationDelegate.onResume(this)\n    }\n\n    override fun attachBaseContext(newBase: Context) {\n        applyOverrideConfiguration(localizationDelegate.updateConfigurationLocale(newBase))\n        super.attachBaseContext(newBase)\n    }\n\n    override fun getApplicationContext(): Context {\n        return localizationDelegate.getApplicationContext(super.getApplicationContext())\n    }\n\n    override fun getResources(): Resources {\n        return localizationDelegate.getResources(super.getResources())\n    }\n\n    fun setLanguage(language: String?) {\n        localizationDelegate.setLanguage(this, language!!)\n    }\n\n    fun setLanguage(locale: Locale?) {\n        localizationDelegate.setLanguage(this, locale!!)\n    }\n\n    val currentLanguage: Locale\n        get() = localizationDelegate.getLanguage(this)\n\n    // Just override method locale change event\n    override fun onBeforeLocaleChanged() {}\n    override fun onAfterLocaleChanged() {}\n}\n```\n\nThen prepare your multilingual content in string resource. \n\n![Multilingual Content](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/02-string_resource.jpg)\n\n\nPublic method on LocalizationActivity\n----\n\nIt have only 4 public methods.\n\n```kotlin\nfun setLanguage(language: String)\nfun setLanguage(language: String, country: Strinng)\nfun setLanguage(locale: Locale)\nfun getCurrentLanguage(): String\n```\n\n`setLanguage` Set the language that you need to change.\n\nFor example\n\n```kotlin\nsetLanguage(\"th\")                             // Language : Thailand\nsetLanguage(\"th\", \"TH\")                       // Language : Thailand, Country : Thai\nsetLanguage(Locale(\"th\", \"TH\"))               // Language : Thailand, Country : Thai\nsetLanguage(\"en\")                             // Language : English\nsetLanguage(\"en\", \"GB\")                       // Language : English,  Country : Great Britain\nsetLanguage(\"en\", \"US\")                       // Language : English,  Country : United States\nsetLanguage(Locale(\"en\", \"US\"))               // Language : English,  Country : United States\nsetLanguage(Locale.KOREA)                     // Language : Korean,   Country : Korea\nsetLanguage(Locale.KOREAN)                    // Language : Korean\nsetLanguage(Locale.CANADA_FRENCH)             // Language : French,   Country : Canada\n```\n\n`getLanguage` Get current language as string locale. \n\nAnd 2 optional override methods.\n\n```kotlin\nfun onBeforeLocaleChanged()\nfun onAfterLocaleChanged()\n```\n\nThis override method will be useful when you need to know when language has changed.\n\n![Back Stack 1](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/04-life_cycle.jpg)\n\nWhen `setLanguage` was called. Current active activity will be recreated to apply the new language.\n\n![Back Stack 2](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/05-step_one.jpg)\n\nPrevious activities in back stack does not change to new language immediately. Until it back to active activity again.\n\n![Back Stack 3](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/06-step_two.jpg)\n \n![Back Stack 4](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/07-step_three.jpg)\n\n![Back Stack 5](https://raw.githubusercontent.com/akexorcist/Android-Localization/master/image/08-step_four.jpg)\n\n\nAction Bar or Toolbar's title\n----\nYou have to call `setTitle(resId)` or `getActionBar().setTitle(resId)` in `onCreate(onSavedInstanceState: Bundle)` to apply the new language.\n\n```kotlin\nclass MainActivity: LocalizationActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        /* ... */\n        setTitle(R.string.main_activity_title)\n    }\n}\n ```\n\n\nHandle state changes\n----\nActivity will be recreate when language has changed as common behavior for configuration changes in Android. Any Activities or Fragments which hold the data should handle the state changes.\n\n\nChange the language in Fragment\n----\nLanguage in fragment will depends on activity. So no need for additional code in Fragment.\n\n\nService\n---\nFor normally usage, just extends from `LocalizationService`\n```kotlin\nclass SimpleService : LocalizationService() {\n    /* ... */\n}\n```\n\nOr using `LocalizationServiceDelegate` with additional code\n```kotlin\nabstract class CustomService : Service() {\n    private val localizationDelegate: LocalizationServiceDelegate by lazy {\n        LocalizationServiceDelegate(this)\n    }\n\n    override fun getBaseContext(): Context {\n        return localizationDelegate.getBaseContext(super.getBaseContext())\n    }\n\n    override fun getApplicationContext(): Context {\n        return localizationDelegate.getApplicationContext(super.getApplicationContext())\n    }\n\n    override fun getResources(): Resources {\n        return localizationDelegate.getResources(super.getResources())\n    }\n}\n```\n \n \nBroadcastReceiver\n---\nBroadcastReceiver is abstract class. So we cannot create LocalizationBroadcastReceiver fot you.\n\nIn this case, you need to convert the context in `onReceive(context: Context, intent: Intent)` to localized context with `Context.toLocalizedContext()` before using.\n\n```kotlin\nclass SimpleBroadcastReceiver : BroadcastReceiver() {\n    override fun onReceive(context: Context, intent: Intent) {\n        val localizedContext = context.toLocalizedContext()\n        /* ... */\n    }\n}\n```\n\n\nLanguage resources optimization in Android App Bundle\n====\nChange the language by library can cause a crash to your app when you publishing your app with Android App Bundle with language resources optimization enabled. \n\nTo fix this, Using the Additional Languages API in Play Core library to download the additional language before.\n\nFor more information about Additional Language API : https://android-developers.googleblog.com/2019/03/the-latest-android-app-bundle-updates.html \n\nIf you don't want to implement this feature in your code, just ignore the language resources optimization by adding the Android App Bundle configuration in your app's build.gradle\n```groovy\nandroid {\n    /* ... */ \n    bundle { \n        language { \n            enableSplit = false \n        } \n    } \n}\n```  \n\nProGuard\n=====\nNormally, there's no require the ProGuard rules for this library. \n\nBut if you want to exclude this library from obfuscate and shrinking. You also can add these code to `proguard-rules.pro` \n```  \n-keep class com.akexorcist.localizationactivity.** { *; }\n-dontwarn com.akexorcist.localizationactivity.**\n```\n\n\nChange Log\n====\nSee [CHANGELOG.md](CHANGELOG.md)\n\n\nLicence\n====\nCopyright 2021 Akexorcist\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n","funding_links":[],"categories":["Libraries","Kotlin"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakexorcist%2FLocalization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakexorcist%2FLocalization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakexorcist%2FLocalization/lists"}