diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java
deleted file mode 100644
index 2b3d257a3..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java
+++ /dev/null
@@ -1,272 +0,0 @@
-package org.yuzu.yuzu_emu.features.settings.utils;
-
-import androidx.annotation.NonNull;
-
-import org.yuzu.yuzu_emu.YuzuApplication;
-import org.yuzu.yuzu_emu.NativeLibrary;
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.FloatSetting;
-import org.yuzu.yuzu_emu.features.settings.model.IntSetting;
-import org.yuzu.yuzu_emu.features.settings.model.Setting;
-import org.yuzu.yuzu_emu.features.settings.model.SettingSection;
-import org.yuzu.yuzu_emu.features.settings.model.Settings;
-import org.yuzu.yuzu_emu.features.settings.model.StringSetting;
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivityView;
-import org.yuzu.yuzu_emu.utils.BiMap;
-import org.yuzu.yuzu_emu.utils.DirectoryInitialization;
-import org.yuzu.yuzu_emu.utils.Log;
-import org.ini4j.Wini;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-/**
- * Contains static methods for interacting with .ini files in which settings are stored.
- */
-public final class SettingsFile {
-    public static final String FILE_NAME_CONFIG = "config";
-
-    public static final String KEY_DESIGN = "design";
-
-    // CPU
-    public static final String KEY_CPU_ACCURACY = "cpu_accuracy";
-    // System
-    public static final String KEY_USE_DOCKED_MODE = "use_docked_mode";
-    public static final String KEY_REGION_INDEX = "region_index";
-    public static final String KEY_LANGUAGE_INDEX = "language_index";
-    public static final String KEY_RENDERER_BACKEND = "backend";
-    // Renderer
-    public static final String KEY_RENDERER_RESOLUTION = "resolution_setup";
-    public static final String KEY_RENDERER_ASPECT_RATIO = "aspect_ratio";
-    public static final String KEY_RENDERER_ACCURACY = "gpu_accuracy";
-    public static final String KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders";
-    public static final String KEY_RENDERER_FORCE_MAX_CLOCK = "force_max_clock";
-    public static final String KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit";
-    public static final String KEY_RENDERER_DEBUG = "debug";
-    public static final String KEY_RENDERER_SPEED_LIMIT = "speed_limit";
-    // Audio
-    public static final String KEY_AUDIO_VOLUME = "volume";
-
-    private static BiMap<String, String> sectionsMap = new BiMap<>();
-
-    static {
-        //TODO: Add members to sectionsMap when game-specific settings are added
-    }
-
-
-    private SettingsFile() {
-    }
-
-    /**
-     * Reads a given .ini file from disk and returns it as a HashMap of Settings, themselves
-     * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
-     * failed.
-     *
-     * @param ini          The ini file to load the settings from
-     * @param isCustomGame
-     * @param view         The current view.
-     * @return An Observable that emits a HashMap of the file's contents, then completes.
-     */
-    static HashMap<String, SettingSection> readFile(final File ini, boolean isCustomGame, SettingsActivityView view) {
-        HashMap<String, SettingSection> sections = new Settings.SettingsSectionMap();
-
-        BufferedReader reader = null;
-
-        try {
-            reader = new BufferedReader(new FileReader(ini));
-
-            SettingSection current = null;
-            for (String line; (line = reader.readLine()) != null; ) {
-                if (line.startsWith("[") && line.endsWith("]")) {
-                    current = sectionFromLine(line, isCustomGame);
-                    sections.put(current.getName(), current);
-                } else if ((current != null)) {
-                    Setting setting = settingFromLine(current, line);
-                    if (setting != null) {
-                        current.putSetting(setting);
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Log.error("[SettingsFile] File not found: " + e.getMessage());
-            if (view != null)
-                view.onSettingsFileNotFound();
-        } catch (IOException e) {
-            Log.error("[SettingsFile] Error reading from: " + e.getMessage());
-            if (view != null)
-                view.onSettingsFileNotFound();
-        } finally {
-            if (reader != null) {
-                try {
-                    reader.close();
-                } catch (IOException e) {
-                    Log.error("[SettingsFile] Error closing: " +  e.getMessage());
-                }
-            }
-        }
-
-        return sections;
-    }
-
-    public static HashMap<String, SettingSection> readFile(final String fileName, SettingsActivityView view) {
-        return readFile(getSettingsFile(fileName), false, view);
-    }
-
-    /**
-     * Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves
-     * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
-     * failed.
-     *
-     * @param gameId the id of the game to load it's settings.
-     * @param view   The current view.
-     */
-    public static HashMap<String, SettingSection> readCustomGameSettings(final String gameId, SettingsActivityView view) {
-        return readFile(getCustomGameSettingsFile(gameId), true, view);
-    }
-
-    /**
-     * Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error
-     * telling why it failed.
-     *
-     * @param fileName The target filename without a path or extension.
-     * @param sections The HashMap containing the Settings we want to serialize.
-     * @param view     The current view.
-     */
-    public static void saveFile(final String fileName, TreeMap<String, SettingSection> sections,
-                                SettingsActivityView view) {
-        File ini = getSettingsFile(fileName);
-
-        try {
-            Wini writer = new Wini(ini);
-
-            Set<String> keySet = sections.keySet();
-            for (String key : keySet) {
-                SettingSection section = sections.get(key);
-                writeSection(writer, section);
-            }
-            writer.store();
-        } catch (IOException e) {
-            Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.getMessage());
-            view.showToastMessage(YuzuApplication.getAppContext().getString(R.string.error_saving, fileName, e.getMessage()), false);
-        }
-    }
-
-
-    public static void saveCustomGameSettings(final String gameId, final HashMap<String, SettingSection> sections) {
-        Set<String> sortedSections = new TreeSet<>(sections.keySet());
-
-        for (String sectionKey : sortedSections) {
-            SettingSection section = sections.get(sectionKey);
-
-            HashMap<String, Setting> settings = section.getSettings();
-            Set<String> sortedKeySet = new TreeSet<>(settings.keySet());
-
-            for (String settingKey : sortedKeySet) {
-                Setting setting = settings.get(settingKey);
-                NativeLibrary.SetUserSetting(gameId, mapSectionNameFromIni(section.getName()), setting.getKey(), setting.getValueAsString());
-            }
-        }
-    }
-
-    private static String mapSectionNameFromIni(String generalSectionName) {
-        if (sectionsMap.getForward(generalSectionName) != null) {
-            return sectionsMap.getForward(generalSectionName);
-        }
-
-        return generalSectionName;
-    }
-
-    private static String mapSectionNameToIni(String generalSectionName) {
-        if (sectionsMap.getBackward(generalSectionName) != null) {
-            return sectionsMap.getBackward(generalSectionName);
-        }
-
-        return generalSectionName;
-    }
-
-    @NonNull
-    private static File getSettingsFile(String fileName) {
-        return new File(
-                DirectoryInitialization.getUserDirectory() + "/config/" + fileName + ".ini");
-    }
-
-    private static File getCustomGameSettingsFile(String gameId) {
-        return new File(DirectoryInitialization.getUserDirectory() + "/GameSettings/" + gameId + ".ini");
-    }
-
-    private static SettingSection sectionFromLine(String line, boolean isCustomGame) {
-        String sectionName = line.substring(1, line.length() - 1);
-        if (isCustomGame) {
-            sectionName = mapSectionNameToIni(sectionName);
-        }
-        return new SettingSection(sectionName);
-    }
-
-    /**
-     * For a line of text, determines what type of data is being represented, and returns
-     * a Setting object containing this data.
-     *
-     * @param current The section currently being parsed by the consuming method.
-     * @param line    The line of text being parsed.
-     * @return A typed Setting containing the key/value contained in the line.
-     */
-    private static Setting settingFromLine(SettingSection current, String line) {
-        String[] splitLine = line.split("=");
-
-        if (splitLine.length != 2) {
-            Log.warning("Skipping invalid config line \"" + line + "\"");
-            return null;
-        }
-
-        String key = splitLine[0].trim();
-        String value = splitLine[1].trim();
-
-        if (value.isEmpty()) {
-            Log.warning("Skipping null value in config line \"" + line + "\"");
-            return null;
-        }
-
-        try {
-            int valueAsInt = Integer.parseInt(value);
-
-            return new IntSetting(key, current.getName(), valueAsInt);
-        } catch (NumberFormatException ex) {
-        }
-
-        try {
-            float valueAsFloat = Float.parseFloat(value);
-
-            return new FloatSetting(key, current.getName(), valueAsFloat);
-        } catch (NumberFormatException ex) {
-        }
-
-        return new StringSetting(key, current.getName(), value);
-    }
-
-    /**
-     * Writes the contents of a Section HashMap to disk.
-     *
-     * @param parser  A Wini pointed at a file on disk.
-     * @param section A section containing settings to be written to the file.
-     */
-    private static void writeSection(Wini parser, SettingSection section) {
-        // Write the section header.
-        String header = section.getName();
-
-        // Write this section's values.
-        HashMap<String, Setting> settings = section.getSettings();
-        Set<String> keySet = settings.keySet();
-
-        for (String key : keySet) {
-            Setting setting = settings.get(key);
-            parser.put(header, setting.getKey(), setting.getValueAsString());
-        }
-    }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
new file mode 100644
index 000000000..8e21c65f0
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
@@ -0,0 +1,245 @@
+package org.yuzu.yuzu_emu.features.settings.utils
+
+import org.ini4j.Wini
+import org.yuzu.yuzu_emu.NativeLibrary
+import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.YuzuApplication
+import org.yuzu.yuzu_emu.features.settings.model.*
+import org.yuzu.yuzu_emu.features.settings.model.Settings.SettingsSectionMap
+import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivityView
+import org.yuzu.yuzu_emu.utils.BiMap
+import org.yuzu.yuzu_emu.utils.DirectoryInitialization
+import org.yuzu.yuzu_emu.utils.Log
+import java.io.*
+import java.util.*
+
+/**
+ * Contains static methods for interacting with .ini files in which settings are stored.
+ */
+object SettingsFile {
+    const val FILE_NAME_CONFIG = "config"
+    const val KEY_DESIGN = "design"
+
+    // CPU
+    const val KEY_CPU_ACCURACY = "cpu_accuracy"
+
+    // System
+    const val KEY_USE_DOCKED_MODE = "use_docked_mode"
+    const val KEY_REGION_INDEX = "region_index"
+    const val KEY_LANGUAGE_INDEX = "language_index"
+    const val KEY_RENDERER_BACKEND = "backend"
+
+    // Renderer
+    const val KEY_RENDERER_RESOLUTION = "resolution_setup"
+    const val KEY_RENDERER_ASPECT_RATIO = "aspect_ratio"
+    const val KEY_RENDERER_ACCURACY = "gpu_accuracy"
+    const val KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders"
+    const val KEY_RENDERER_FORCE_MAX_CLOCK = "force_max_clock"
+    const val KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit"
+    const val KEY_RENDERER_DEBUG = "debug"
+    const val KEY_RENDERER_SPEED_LIMIT = "speed_limit"
+
+    // Audio
+    const val KEY_AUDIO_VOLUME = "volume"
+    private val sectionsMap = BiMap<String?, String?>()
+
+    /**
+     * Reads a given .ini file from disk and returns it as a HashMap of Settings, themselves
+     * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
+     * failed.
+     *
+     * @param ini          The ini file to load the settings from
+     * @param isCustomGame
+     * @param view         The current view.
+     * @return An Observable that emits a HashMap of the file's contents, then completes.
+     */
+    private fun readFile(
+        ini: File?,
+        isCustomGame: Boolean,
+        view: SettingsActivityView?
+    ): HashMap<String, SettingSection?> {
+        val sections: HashMap<String, SettingSection?> = SettingsSectionMap()
+        var reader: BufferedReader? = null
+        try {
+            reader = BufferedReader(FileReader(ini))
+            var current: SettingSection? = null
+            var line: String?
+            while (reader.readLine().also { line = it } != null) {
+                if (line!!.startsWith("[") && line!!.endsWith("]")) {
+                    current = sectionFromLine(line!!, isCustomGame)
+                    sections[current.name] = current
+                } else if (current != null) {
+                    val setting = settingFromLine(current, line!!)
+                    if (setting != null) {
+                        current.putSetting(setting)
+                    }
+                }
+            }
+        } catch (e: FileNotFoundException) {
+            Log.error("[SettingsFile] File not found: " + e.message)
+            view?.onSettingsFileNotFound()
+        } catch (e: IOException) {
+            Log.error("[SettingsFile] Error reading from: " + e.message)
+            view?.onSettingsFileNotFound()
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close()
+                } catch (e: IOException) {
+                    Log.error("[SettingsFile] Error closing: " + e.message)
+                }
+            }
+        }
+        return sections
+    }
+
+    fun readFile(fileName: String, view: SettingsActivityView): HashMap<String, SettingSection?> {
+        return readFile(getSettingsFile(fileName), false, view)
+    }
+
+    /**
+     * Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves
+     * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
+     * failed.
+     *
+     * @param gameId the id of the game to load it's settings.
+     * @param view   The current view.
+     */
+    fun readCustomGameSettings(
+        gameId: String,
+        view: SettingsActivityView
+    ): HashMap<String, SettingSection?> {
+        return readFile(getCustomGameSettingsFile(gameId), true, view)
+    }
+
+    /**
+     * Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error
+     * telling why it failed.
+     *
+     * @param fileName The target filename without a path or extension.
+     * @param sections The HashMap containing the Settings we want to serialize.
+     * @param view     The current view.
+     */
+    fun saveFile(
+        fileName: String,
+        sections: TreeMap<String, SettingSection>,
+        view: SettingsActivityView
+    ) {
+        val ini = getSettingsFile(fileName)
+        try {
+            val writer = Wini(ini)
+            val keySet: Set<String> = sections.keys
+            for (key in keySet) {
+                val section = sections[key]
+                writeSection(writer, section!!)
+            }
+            writer.store()
+        } catch (e: IOException) {
+            Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.message)
+            view.showToastMessage(
+                YuzuApplication.appContext
+                    .getString(R.string.error_saving, fileName, e.message),
+                false
+            )
+        }
+    }
+
+    fun saveCustomGameSettings(gameId: String?, sections: HashMap<String, SettingSection?>) {
+        val sortedSections: Set<String> = TreeSet(sections.keys)
+        for (sectionKey in sortedSections) {
+            val section = sections[sectionKey]
+            val settings = section!!.settings
+            val sortedKeySet: Set<String> = TreeSet(settings.keys)
+            for (settingKey in sortedKeySet) {
+                val setting = settings[settingKey]
+                NativeLibrary.SetUserSetting(
+                    gameId, mapSectionNameFromIni(
+                        section.name
+                    ), setting!!.key, setting.valueAsString
+                )
+            }
+        }
+    }
+
+    private fun mapSectionNameFromIni(generalSectionName: String): String? {
+        return if (sectionsMap.getForward(generalSectionName) != null) {
+            sectionsMap.getForward(generalSectionName)
+        } else generalSectionName
+    }
+
+    private fun mapSectionNameToIni(generalSectionName: String): String {
+        return if (sectionsMap.getBackward(generalSectionName) != null) {
+            sectionsMap.getBackward(generalSectionName).toString()
+        } else generalSectionName
+    }
+
+    private fun getSettingsFile(fileName: String): File {
+        return File(
+            DirectoryInitialization.userDirectory + "/config/" + fileName + ".ini"
+        )
+    }
+
+    private fun getCustomGameSettingsFile(gameId: String): File {
+        return File(DirectoryInitialization.userDirectory + "/GameSettings/" + gameId + ".ini")
+    }
+
+    private fun sectionFromLine(line: String, isCustomGame: Boolean): SettingSection {
+        var sectionName: String = line.substring(1, line.length - 1)
+        if (isCustomGame) {
+            sectionName = mapSectionNameToIni(sectionName)
+        }
+        return SettingSection(sectionName)
+    }
+
+    /**
+     * For a line of text, determines what type of data is being represented, and returns
+     * a Setting object containing this data.
+     *
+     * @param current The section currently being parsed by the consuming method.
+     * @param line    The line of text being parsed.
+     * @return A typed Setting containing the key/value contained in the line.
+     */
+    private fun settingFromLine(current: SettingSection, line: String): Setting? {
+        val splitLine = line.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+        if (splitLine.size != 2) {
+            Log.warning("Skipping invalid config line \"$line\"")
+            return null
+        }
+        val key = splitLine[0].trim { it <= ' ' }
+        val value = splitLine[1].trim { it <= ' ' }
+        if (value.isEmpty()) {
+            Log.warning("Skipping null value in config line \"$line\"")
+            return null
+        }
+        try {
+            val valueAsInt = value.toInt()
+            return IntSetting(key, current.name, valueAsInt)
+        } catch (_: NumberFormatException) {
+        }
+        try {
+            val valueAsFloat = value.toFloat()
+            return FloatSetting(key, current.name, valueAsFloat)
+        } catch (_: NumberFormatException) {
+        }
+        return StringSetting(key, current.name, value)
+    }
+
+    /**
+     * Writes the contents of a Section HashMap to disk.
+     *
+     * @param parser  A Wini pointed at a file on disk.
+     * @param section A section containing settings to be written to the file.
+     */
+    private fun writeSection(parser: Wini, section: SettingSection) {
+        // Write the section header.
+        val header = section.name
+
+        // Write this section's values.
+        val settings = section.settings
+        val keySet: Set<String> = settings.keys
+        for (key in keySet) {
+            val setting = settings[key]
+            parser.put(header, setting!!.key, setting.valueAsString)
+        }
+    }
+}