-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[Android 13+] Support per-app language preferences #12093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
b888dc7
87693a2
3532ac9
da106e2
980a35a
70416e7
35abb99
c7bf498
7f10312
205466c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,11 +3,14 @@ | |
| import android.app.Application; | ||
| import android.content.Context; | ||
| import android.content.SharedPreferences; | ||
| import android.os.Build; | ||
| import android.util.Log; | ||
|
|
||
| import androidx.annotation.NonNull; | ||
| import androidx.appcompat.app.AppCompatDelegate; | ||
| import androidx.core.app.NotificationChannelCompat; | ||
| import androidx.core.app.NotificationManagerCompat; | ||
| import androidx.core.os.LocaleListCompat; | ||
| import androidx.preference.PreferenceManager; | ||
|
|
||
| import com.jakewharton.processphoenix.ProcessPhoenix; | ||
|
|
@@ -122,6 +125,29 @@ public void onCreate() { | |
| configureRxJavaErrorHandler(); | ||
|
|
||
| YoutubeStreamExtractor.setPoTokenProvider(PoTokenProviderImpl.INSTANCE); | ||
|
|
||
| if (Build.VERSION.SDK_INT >= 33) { | ||
| ensureAppLanguagePreferenceIsMigrated(prefs); | ||
| } | ||
| } | ||
|
|
||
| private void ensureAppLanguagePreferenceIsMigrated(final SharedPreferences prefs) { | ||
| final String appLanguageDefaultValue = getString(R.string.default_localization_key); | ||
| final String appLanguageKey = getString(R.string.app_language_key); | ||
| final String appLanguageCurrentValue = prefs.getString(appLanguageKey, null); | ||
| if (appLanguageCurrentValue != null) { | ||
| // Migrate to Android per-app language settings | ||
| prefs.edit().remove(appLanguageKey).apply(); | ||
| if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { | ||
| try { | ||
| AppCompatDelegate.setApplicationLocales( | ||
| LocaleListCompat.forLanguageTags(appLanguageCurrentValue) | ||
| ); | ||
| } catch (final RuntimeException e) { | ||
| Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); | ||
| } | ||
| } | ||
| } | ||
|
||
| } | ||
|
|
||
| @Override | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,15 @@ | ||
| package org.schabi.newpipe.settings; | ||
|
|
||
| import android.content.Context; | ||
| import android.content.Intent; | ||
| import android.net.Uri; | ||
| import android.os.Build; | ||
| import android.os.Bundle; | ||
| import android.provider.Settings; | ||
| import android.util.Log; | ||
| import android.widget.Toast; | ||
|
|
||
| import androidx.appcompat.app.AppCompatDelegate; | ||
| import androidx.preference.Preference; | ||
|
|
||
| import org.schabi.newpipe.DownloaderImpl; | ||
|
|
@@ -17,6 +22,7 @@ | |
| import org.schabi.newpipe.util.image.PreferredImageQuality; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Locale; | ||
|
|
||
| public class ContentSettingsFragment extends BasePreferenceFragment { | ||
| private String youtubeRestrictedModeEnabledKey; | ||
|
|
@@ -37,6 +43,26 @@ public void onCreatePreferences(final Bundle savedInstanceState, final String ro | |
| .getPreferredContentCountry(requireContext()); | ||
| initialLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en"); | ||
|
|
||
| if (Build.VERSION.SDK_INT >= 33) { | ||
| requirePreference(R.string.app_language_key).setVisible(false); | ||
| final Preference newAppLanguagePref = | ||
| requirePreference(R.string.app_language_android_13_and_up_key); | ||
| newAppLanguagePref.setSummaryProvider(preference -> { | ||
| final Locale customLocale = AppCompatDelegate.getApplicationLocales().get(0); | ||
| if (customLocale != null) { | ||
| return customLocale.getDisplayName(); | ||
| } | ||
| return getString(R.string.systems_language); | ||
| }); | ||
| newAppLanguagePref.setOnPreferenceClickListener(preference -> { | ||
| final Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS) | ||
| .setData(Uri.fromParts("package", requireContext().getPackageName(), null)); | ||
| startActivity(intent); | ||
|
Comment on lines
+52
to
+54
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a very edge case, but if the user has disabled settings or if some ROMs are broken (hello weird Android TV devices), this would crash the app due to no app being able to handle the intent. |
||
| return true; | ||
| }); | ||
| newAppLanguagePref.setVisible(true); | ||
| } | ||
|
|
||
| final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); | ||
| imageQualityPreference.setOnPreferenceChangeListener( | ||
| (preference, newValue) -> { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| unqualifiedResLocale=en-US |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,13 @@ | |
| app:iconSpaceReserved="false" | ||
| app:useSimpleSummaryProvider="true" /> | ||
|
|
||
| <Preference | ||
| android:key="@string/app_language_android_13_and_up_key" | ||
| android:title="@string/app_language_title" | ||
| app:isPreferenceVisible="false" | ||
| app:singleLineTitle="false" | ||
| app:iconSpaceReserved="false" /> | ||
|
Comment on lines
+16
to
+21
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a separate |
||
|
|
||
| <ListPreference | ||
| android:defaultValue="@string/default_localization_key" | ||
| android:entries="@array/language_names" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't pay attention to new languages being added from Weblate, this might lead to half-translated being proposed to the user. Currently the list of languages is manually kept in
settings_keys.xml, so when new languages are added through Weblate they don't automatically appear in the app menu. However, I'm fine with switching to the new behavior, as it would avoid work to keep the language list up to date. Is it possible to access the locale config from within the app, so we can delete the list of languages insettings_keys.xmland use the autogenerated locale config even for the pre-Android-13 language picker?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found LocaleManager#getOverrideLocaleConfig but it sounds like that method is only to get a
LocaleConfigthat's already been set withsetOverrideLocaleConfig(). As far as I can tell, we would have to manually generate aLocaleConfiginstead of using the auto-generated one if we wanted to use it for this.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could find the data under
app/build/generated/res/localeConfig/debug/xml/_generated_res_locale_config.xmlafter running the build, with this data inside:So in theory the data is there, but in practice I think we better not access it by manually opening the xml since it's not officially supported. So yeah let's keep the previous behavior.