Switch to the new native per-app language preference APIs on Android 13

This commit is contained in:
Cameron Gutman
2022-06-18 14:19:19 -05:00
parent c743949df5
commit 2e14002442
8 changed files with 115 additions and 21 deletions

View File

@@ -44,6 +44,7 @@
android:roundIcon="@mipmap/ic_launcher"
android:installLocation="auto"
android:gwpAsanMode="always"
android:localeConfig="@xml/locales_config"
android:theme="@style/AppTheme">
<provider

View File

@@ -0,0 +1,51 @@
package com.limelight.preferences;
import android.annotation.TargetApi;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.preference.ListPreference;
import android.provider.Settings;
import android.util.AttributeSet;
public class LanguagePreference extends ListPreference {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LanguagePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LanguagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public LanguagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LanguagePreference(Context context) {
super(context);
}
@Override
protected void onClick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
try {
// Launch the Android native app locale settings page
Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + getContext().getPackageName()));
getContext().startActivity(intent, null);
return;
} catch (ActivityNotFoundException e) {
// App locale settings should be present on all Android 13 devices,
// but if not, we'll launch the old language chooser.
}
}
// If we don't have native app locale settings, launch the normal dialog
super.onClick();
}
}

View File

@@ -319,6 +319,12 @@ public class PreferenceConfiguration {
.apply();
}
public static void completeLanguagePreferenceMigration(Context context) {
// Put our language option back to default which tells us that we've already migrated it
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putString(LANGUAGE_PREF_STRING, DEFAULT_LANGUAGE).apply();
}
public static boolean isShieldAtvFirmwareWithBrokenHdr() {
// This particular Shield TV firmware crashes when using HDR
// https://www.nvidia.com/en-us/geforce/forums/notifications/comment/155192/

View File

@@ -80,16 +80,20 @@ public class StreamSettings extends Activity {
}
@Override
// NOTE: This will NOT be called on Android 13+ with android:enableOnBackInvokedCallback="true"
public void onBackPressed() {
finish();
// Check for changes that require a UI reload to take effect
PreferenceConfiguration newPrefs = PreferenceConfiguration.readPreferences(this);
if (!newPrefs.language.equals(previousPrefs.language)) {
// Restart the PC view to apply UI changes
Intent intent = new Intent(this, PcView.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, null);
// Language changes are handled via configuration changes in Android 13+,
// so manual activity relaunching is no longer required.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
PreferenceConfiguration newPrefs = PreferenceConfiguration.readPreferences(this);
if (!newPrefs.language.equals(previousPrefs.language)) {
// Restart the PC view to apply UI changes
Intent intent = new Intent(this, PcView.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, null);
}
}
}

View File

@@ -4,6 +4,7 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.GameManager;
import android.app.GameState;
import android.app.LocaleManager;
import android.app.UiModeManager;
import android.content.Context;
import android.content.DialogInterface;
@@ -11,6 +12,7 @@ import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.os.Build;
import android.os.LocaleList;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -64,21 +66,29 @@ public class UiHelper {
{
String locale = PreferenceConfiguration.readPreferences(activity).language;
if (!locale.equals(PreferenceConfiguration.DEFAULT_LANGUAGE)) {
Configuration config = new Configuration(activity.getResources().getConfiguration());
// Some locales include both language and country which must be separated
// before calling the Locale constructor.
if (locale.contains("-"))
{
config.locale = new Locale(locale.substring(0, locale.indexOf('-')),
locale.substring(locale.indexOf('-') + 1));
}
else
{
config.locale = new Locale(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// On Android 13, migrate this non-default language setting into the OS native API
LocaleManager localeManager = activity.getSystemService(LocaleManager.class);
localeManager.setApplicationLocales(LocaleList.forLanguageTags(locale));
PreferenceConfiguration.completeLanguagePreferenceMigration(activity);
}
else {
Configuration config = new Configuration(activity.getResources().getConfiguration());
activity.getResources().updateConfiguration(config, activity.getResources().getDisplayMetrics());
// Some locales include both language and country which must be separated
// before calling the Locale constructor.
if (locale.contains("-"))
{
config.locale = new Locale(locale.substring(0, locale.indexOf('-')),
locale.substring(locale.indexOf('-') + 1));
}
else
{
config.locale = new Locale(locale);
}
activity.getResources().updateConfiguration(config, activity.getResources().getDisplayMetrics());
}
}
}

View File

@@ -43,6 +43,7 @@
<item>71</item>
</string-array>
<!-- Don't forget to update locales_config.xml when you modify this! -->
<string-array name="language_names" translatable="false">
<item>Default</item>
<item>English</item>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Don't forget to update arrays.xml when you modify this file! -->
<locale android:name="en"/>
<locale android:name="it"/>
<locale android:name="ja"/>
<locale android:name="ru"/>
<locale android:name="nl"/>
<locale android:name="zh-CN"/>
<locale android:name="zh-TW"/>
<locale android:name="ko"/>
<locale android:name="es"/>
<locale android:name="fr"/>
<locale android:name="de"/>
<locale android:name="ro"/>
<locale android:name="uk"/>
<locale android:name="nb-NO"/>
<locale android:name="vi"/>
<locale android:name="hu"/>
<locale android:name="el"/>
</locale-config>

View File

@@ -165,7 +165,7 @@
android:title="@string/title_checkbox_enable_pip"
android:summary="@string/summary_checkbox_enable_pip"
android:defaultValue="false" />
<ListPreference
<com.limelight.preferences.LanguagePreference
android:key="list_languages"
android:title="@string/title_language_list"
android:entries="@array/language_names"