diff --git a/app/build.gradle b/app/build.gradle
index c8a67aac..0dda02c2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -40,6 +40,13 @@ android {
// Only enable separate process for release builds
manifestPlaceholders += [emulationProcess: ""]
+
+ def locales = ["en", "de", "el", "es", "es-419", "fr", "hu", "id", "it", "ja", "ko", "pl", "ru", "ta", "zh-Hans", "zh-Hant"]
+
+ // Add available locales to the build config so that they can be accessed from the app
+ buildConfigField "String[]", "AVAILABLE_APP_LANGUAGES", "new String[]{\"" + locales.join("\",\"") + "\"}"
+ // Uncomment the following line whenever AAPT2 will properly support BCP47 language tags
+ //resourceConfigurations += locales
}
/* JVM Bytecode Options */
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9700d9d2..a5f3218f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -20,6 +20,7 @@
android:icon="@drawable/logo_skyline"
android:isGame="true"
android:label="${appLabel}"
+ android:localeConfig="@xml/locales_config"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
@@ -116,6 +117,15 @@
+
+
+
+
diff --git a/app/src/main/java/emu/skyline/preference/LanguagePreference.kt b/app/src/main/java/emu/skyline/preference/LanguagePreference.kt
new file mode 100644
index 00000000..445b6433
--- /dev/null
+++ b/app/src/main/java/emu/skyline/preference/LanguagePreference.kt
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: MPL-2.0
+ * Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
+ */
+
+package emu.skyline.preference
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.core.os.LocaleListCompat
+import androidx.preference.ListPreference
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.Preference.SummaryProvider
+import emu.skyline.BuildConfig
+import emu.skyline.R
+import java.util.*
+
+private const val SystemLanguage = "syslang"
+
+class LanguagePreference @JvmOverloads constructor(context : Context, attrs : AttributeSet? = null, defStyleAttr : Int = androidx.preference.R.attr.preferenceStyle) : ListPreference(context, attrs, defStyleAttr) {
+ init {
+ entries = arrayOf(systemEntry) + BuildConfig.AVAILABLE_APP_LANGUAGES.map { Locale.forLanguageTag(it).run { getDisplayName(this) } }
+ entryValues = arrayOf(SystemLanguage) + BuildConfig.AVAILABLE_APP_LANGUAGES
+
+ value = AppCompatDelegate.getApplicationLocales()[0]?.toLanguageTag() ?: SystemLanguage
+
+ onPreferenceChangeListener = OnPreferenceChangeListener { _, newValue ->
+ if (newValue == SystemLanguage) {
+ AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+ } else {
+ val newLocale = LocaleListCompat.forLanguageTags(newValue as String)
+ AppCompatDelegate.setApplicationLocales(newLocale)
+ }
+ true
+ }
+
+ summaryProvider = SummaryProvider {
+ AppCompatDelegate.getApplicationLocales()[0]?.displayName ?: systemEntry
+ }
+ }
+
+ private val systemEntry : String get() = context.getString(R.string.app_language_default)
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b0beb3b1..61e12817 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -41,6 +41,8 @@
Appearance
Theme
+ App Language
+ Use System Default
Game Display Layout
Games Sorting Order
Group Games By Format
diff --git a/app/src/main/res/xml/app_preferences.xml b/app/src/main/res/xml/app_preferences.xml
index 472a0862..ee23aefb 100644
--- a/app/src/main/res/xml/app_preferences.xml
+++ b/app/src/main/res/xml/app_preferences.xml
@@ -28,6 +28,10 @@
app:key="app_theme"
app:title="@string/theme"
app:useSimpleSummaryProvider="true" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+