]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
Combine drawable files. https://redmine.stoutner.com/issues/794
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / fragments / SettingsFragment.java
index dcc548939e58c356020cf3a0baba24b67161950a..05b82dff6e8a2bddfb3b668a4f007acb0534cc95 100644 (file)
 /*
- * Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2022 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
  *
- * Privacy Browser is free software: you can redistribute it and/or modify
+ * Privacy Browser Android is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
- * Privacy Browser is distributed in the hope that it will be useful,
+ * Privacy Browser Android is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.stoutner.privacybrowser.fragments;
 
 import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.os.Build;
 import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
+import android.os.Handler;
+import android.os.Looper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.webkit.WebView;
+import android.widget.ArrayAdapter;
 
-import com.stoutner.privacybrowser.R;
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceFragmentCompat;
 
-public class SettingsFragment extends PreferenceFragment {
-    private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
-    private SharedPreferences savedPreferences;
+import com.stoutner.privacybrowser.R;
+import com.stoutner.privacybrowser.activities.MainWebViewActivity;
+import com.stoutner.privacybrowser.helpers.ProxyHelper;
+
+import java.util.Objects;
+
+public class SettingsFragment extends PreferenceFragmentCompat {
+    // Declare the class variables.
+    private int currentThemeStatus;
+    private String defaultUserAgent;
+    private ArrayAdapter<CharSequence> userAgentNamesArray;
+    private String[] translatedUserAgentNamesArray;
+    private String[] userAgentDataArray;
+    private String[] appThemeEntriesStringArray;
+    private String[] appThemeEntryValuesStringArray;
+    private String[] webViewThemeEntriesStringArray;
+    private String[] webViewThemeEntryValuesStringArray;
+    private SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener;
+
+    // Declare the class views.
+    private Preference javaScriptPreference;
+    private Preference cookiesPreference;
+    private Preference domStoragePreference;
+    private Preference formDataPreference;  // The form data preference can be removed once the minimum API >= 26.
+    private Preference userAgentPreference;
+    private Preference customUserAgentPreference;
+    private Preference incognitoModePreference;
+    private Preference allowScreenshotsPreference;
+    private Preference easyListPreference;
+    private Preference easyPrivacyPreference;
+    private Preference fanboyAnnoyanceListPreference;
+    private Preference fanboySocialBlockingListPreference;
+    private Preference ultraListPreference;
+    private Preference ultraPrivacyPreference;
+    private Preference blockAllThirdPartyRequestsPreference;
+    private Preference googleAnalyticsPreference;
+    private Preference facebookClickIdsPreference;
+    private Preference twitterAmpRedirectsPreference;
+    private Preference searchPreference;
+    private Preference searchCustomURLPreference;
+    private Preference proxyPreference;
+    private Preference proxyCustomUrlPreference;
+    private Preference fullScreenBrowsingModePreference;
+    private Preference hideAppBarPreference;
+    private Preference clearEverythingPreference;
+    private Preference clearCookiesPreference;
+    private Preference clearDomStoragePreference;
+    private Preference clearFormDataPreference;  // The clear form data preference can be removed once the minimum API >= 26.
+    private Preference clearLogcatPreference;
+    private Preference clearCachePreference;
+    private Preference homepagePreference;
+    private Preference fontSizePreference;
+    private Preference openIntentsInNewTabPreference;
+    private Preference swipeToRefreshPreference;
+    private Preference downloadWithExternalAppPreference;
+    private Preference scrollAppBarPreference;
+    private Preference bottomAppBarPreference;
+    private Preference displayAdditionalAppBarIconsPreference;
+    private Preference appThemePreference;
+    private Preference webViewThemePreference;
+    private Preference wideViewportPreference;
+    private Preference displayWebpageImagesPreference;
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.preferences);
-
-        // Initialize savedPreferences.
-        savedPreferences = getPreferenceScreen().getSharedPreferences();
-
-        // Get handles for the preferences we need to modify.
-        final Preference javaScriptPreference = findPreference("javascript_enabled");
-        final Preference firstPartyCookiesPreference = findPreference("first_party_cookies_enabled");
-        final Preference thirdPartyCookiesPreference = findPreference("third_party_cookies_enabled");
-        final Preference domStoragePreference = findPreference("dom_storage_enabled");
-        final Preference saveFormDataPreference = findPreference("save_form_data_enabled");
-        final Preference userAgentPreference = findPreference("user_agent");
-        final Preference customUserAgentPreference = findPreference("custom_user_agent");
-        final Preference blockAdsPreference = findPreference("block_ads");
-        final Preference incognitoModePreference = findPreference("incognito_mode");
-        final Preference doNotTrackPreference = findPreference("do_not_track");
-        final Preference proxyThroughOrbotPreference = findPreference("proxy_through_orbot");
-        final Preference torHomepagePreference = findPreference("tor_homepage");
-        final Preference torSearchPreference = findPreference("tor_search");
-        final Preference torSearchCustomURLPreference = findPreference("tor_search_custom_url");
-        final Preference searchPreference = findPreference("search");
-        final Preference searchCustomURLPreference = findPreference("search_custom_url");
-        final Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
-        final Preference hideSystemBarsPreference = findPreference("hide_system_bars");
-        final Preference translucentNavigationBarPreference = findPreference("translucent_navigation_bar");
-        final Preference homepagePreference = findPreference("homepage");
-        final Preference defaultFontSizePreference = findPreference("default_font_size");
-        final Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
-        final Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
-
-        // Set dependencies.
-        domStoragePreference.setDependency("javascript_enabled");
-        torHomepagePreference.setDependency("proxy_through_orbot");
-        torSearchPreference.setDependency("proxy_through_orbot");
-        hideSystemBarsPreference.setDependency("full_screen_browsing_mode");
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        // Load the preferences from the XML file.
+        setPreferencesFromResource(R.xml.preferences, rootKey);
+
+        // Get a handle for the activity.
+        Activity activity = getActivity();
+
+        // Remove the lint warning below that `getApplicationContext()` might produce a null pointer exception.
+        assert activity != null;
+
+        // Get a handle for the resources.
+        Resources resources = getResources();
+
+        // Get the current theme status.
+        currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+
+        // Get a handle for the shared preferences.
+        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
+
+        // Remove the incorrect warning below that the shared preferences might be null.
+        assert sharedPreferences != null;
+
+        // Get handles for the preferences.
+        javaScriptPreference = findPreference("javascript");
+        cookiesPreference = findPreference(getString(R.string.cookies_key));
+        domStoragePreference = findPreference("dom_storage");
+        formDataPreference = findPreference("save_form_data");  // The form data preference can be removed once the minimum API >= 26.
+        userAgentPreference = findPreference("user_agent");
+        customUserAgentPreference = findPreference("custom_user_agent");
+        incognitoModePreference = findPreference("incognito_mode");
+        allowScreenshotsPreference = findPreference(getString(R.string.allow_screenshots_key));
+        easyListPreference = findPreference("easylist");
+        easyPrivacyPreference = findPreference("easyprivacy");
+        fanboyAnnoyanceListPreference = findPreference("fanboys_annoyance_list");
+        fanboySocialBlockingListPreference = findPreference("fanboys_social_blocking_list");
+        ultraListPreference = findPreference("ultralist");
+        ultraPrivacyPreference = findPreference("ultraprivacy");
+        blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
+        googleAnalyticsPreference = findPreference("google_analytics");
+        facebookClickIdsPreference = findPreference("facebook_click_ids");
+        twitterAmpRedirectsPreference = findPreference("twitter_amp_redirects");
+        searchPreference = findPreference("search");
+        searchCustomURLPreference = findPreference("search_custom_url");
+        proxyPreference = findPreference("proxy");
+        proxyCustomUrlPreference = findPreference(getString(R.string.proxy_custom_url_key));
+        fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
+        hideAppBarPreference = findPreference("hide_app_bar");
+        clearEverythingPreference = findPreference("clear_everything");
+        clearCookiesPreference = findPreference("clear_cookies");
+        clearDomStoragePreference = findPreference("clear_dom_storage");
+        clearFormDataPreference = findPreference("clear_form_data");  // The clear form data preference can be removed once the minimum API >= 26.
+        clearLogcatPreference = findPreference(getString(R.string.clear_logcat_key));
+        clearCachePreference = findPreference("clear_cache");
+        homepagePreference = findPreference("homepage");
+        fontSizePreference = findPreference("font_size");
+        openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
+        swipeToRefreshPreference = findPreference("swipe_to_refresh");
+        downloadWithExternalAppPreference = findPreference(getString(R.string.download_with_external_app_key));
+        scrollAppBarPreference = findPreference(getString(R.string.scroll_app_bar_key));
+        bottomAppBarPreference = findPreference(getString(R.string.bottom_app_bar_key));
+        displayAdditionalAppBarIconsPreference = findPreference(getString(R.string.display_additional_app_bar_icons_key));
+        appThemePreference = findPreference("app_theme");
+        webViewThemePreference = findPreference("webview_theme");
+        wideViewportPreference = findPreference("wide_viewport");
+        displayWebpageImagesPreference = findPreference("display_webpage_images");
+
+        // Remove the lint warnings below that the preferences might be null.
+        assert javaScriptPreference != null;
+        assert cookiesPreference != null;
+        assert domStoragePreference != null;
+        assert formDataPreference != null;
+        assert userAgentPreference != null;
+        assert customUserAgentPreference != null;
+        assert incognitoModePreference != null;
+        assert allowScreenshotsPreference != null;
+        assert easyListPreference != null;
+        assert easyPrivacyPreference != null;
+        assert fanboyAnnoyanceListPreference != null;
+        assert fanboySocialBlockingListPreference != null;
+        assert ultraListPreference != null;
+        assert ultraPrivacyPreference != null;
+        assert blockAllThirdPartyRequestsPreference != null;
+        assert googleAnalyticsPreference != null;
+        assert facebookClickIdsPreference != null;
+        assert twitterAmpRedirectsPreference != null;
+        assert searchPreference != null;
+        assert searchCustomURLPreference != null;
+        assert proxyPreference != null;
+        assert proxyCustomUrlPreference != null;
+        assert fullScreenBrowsingModePreference != null;
+        assert hideAppBarPreference != null;
+        assert clearEverythingPreference != null;
+        assert clearCookiesPreference != null;
+        assert clearDomStoragePreference != null;
+        assert clearFormDataPreference != null;
+        assert clearLogcatPreference != null;
+        assert clearCachePreference != null;
+        assert homepagePreference != null;
+        assert fontSizePreference != null;
+        assert openIntentsInNewTabPreference != null;
+        assert swipeToRefreshPreference != null;
+        assert downloadWithExternalAppPreference != null;
+        assert scrollAppBarPreference != null;
+        assert bottomAppBarPreference != null;
+        assert displayAdditionalAppBarIconsPreference != null;
+        assert appThemePreference != null;
+        assert webViewThemePreference != null;
+        assert wideViewportPreference != null;
+        assert displayWebpageImagesPreference != null;
+
+        // Set the preference dependencies.
+        hideAppBarPreference.setDependency("full_screen_browsing_mode");
+        domStoragePreference.setDependency("javascript");
 
         // Get strings from the preferences.
-        String torSearchString = savedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
-        String searchString = savedPreferences.getString("search", "https://duckduckgo.com/html/?q=");
+        String userAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
+        String searchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
+        String proxyString = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
+
+        // Get booleans that are used in multiple places from the preferences.
+        boolean javaScriptEnabled = sharedPreferences.getBoolean("javascript", false);
+        boolean fanboyAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
+        boolean fanboySocialBlockingEnabled = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
+        boolean fullScreenBrowsingMode = sharedPreferences.getBoolean("full_screen_browsing_mode", false);
+        boolean clearEverything = sharedPreferences.getBoolean("clear_everything", true);
+
+        // Remove the form data preferences if the API is >= 26 as they no longer do anything.
+        if (Build.VERSION.SDK_INT >= 26) {
+            // Get handles for the categories.
+            PreferenceCategory privacyCategory = findPreference("privacy");
+            PreferenceCategory clearAndExitCategory = findPreference("clear_and_exit");
+
+            // Remove the incorrect lint warnings below that the preference categories might be null.
+            assert privacyCategory != null;
+            assert clearAndExitCategory != null;
+
+            // Remove the form data preferences.
+            privacyCategory.removePreference(formDataPreference);
+            clearAndExitCategory.removePreference(clearFormDataPreference);
+        }
 
-        // Get booleans from the preferences.
-        boolean javaScriptEnabledBoolean = savedPreferences.getBoolean("javascript_enabled", false);
-        boolean firstPartyCookiesEnabledBoolean = savedPreferences.getBoolean("first_party_cookies_enabled", false);
-        boolean thirdPartyCookiesEnabledBoolean = savedPreferences.getBoolean("third_party_cookies_enabled", false);
-        boolean proxyThroughOrbotBoolean = savedPreferences.getBoolean("proxy_through_orbot", false);
-        boolean fullScreenBrowsingModeBoolean = savedPreferences.getBoolean("full_screen_browsing_mode", false);
-        boolean hideSystemBarsBoolean = savedPreferences.getBoolean("hide_system_bars", false);
+        // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
+        fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
 
-        // Only enable `thirdPartyCookiesPreference` if `firstPartyCookiesEnabledBoolean` is `true` and API >= 21.
-        thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabledBoolean && (Build.VERSION.SDK_INT >= 21));
 
-        // We need to inflated a `WebView` to get the default user agent.
+        // Inflate a WebView to get the default user agent.
         LayoutInflater inflater = getActivity().getLayoutInflater();
-        // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because we don't want to display `bare_webview` on the screen.  `false` does not attach the view to the root.
+
+        // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because the `bare_webview` will not be displayed.
         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
-        final WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview);
 
-        // Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded.
-        switch (savedPreferences.getString("user_agent", "PrivacyBrowser/1.0")) {
-            case "WebView default user agent":
+        // Get a handle for a bare WebView.
+        WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
+
+        // Get the default user agent.
+        defaultUserAgent = bareWebView.getSettings().getUserAgentString();
+
+        // Get the user agent arrays.
+        userAgentNamesArray = ArrayAdapter.createFromResource(requireContext(), R.array.user_agent_names, R.layout.spinner_item);
+        translatedUserAgentNamesArray = resources.getStringArray(R.array.translated_user_agent_names);
+        userAgentDataArray = resources.getStringArray(R.array.user_agent_data);
+
+        // Get the array position of the user agent name.
+        int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
+
+        // Populate the user agent summary.
+        switch (userAgentArrayPosition) {
+            case MainWebViewActivity.UNRECOGNIZED_USER_AGENT:  // The user agent name is not on the canonical list.
+                // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names.  Use the current user agent entry name as the summary.
+                userAgentPreference.setSummary(userAgentName);
+                break;
+
+            case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
                 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
-                userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
+                userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + defaultUserAgent);
                 break;
 
-            case "Custom user agent":
-                // We can't use the string from the array because it is referenced in code and can't be translated.
+            case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
+                // Set the summary text.
                 userAgentPreference.setSummary(R.string.custom_user_agent);
                 break;
 
             default:
-                // Display the user agent from the preference as the summary text.
-                userAgentPreference.setSummary(savedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
-                break;
+                // Get the user agent summary from the user agent data array.
+                userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
         }
 
-        // Set the summary text for "customUserAgentPreference" (the default is `PrivacyBrowser/1.0`) and enable it if `userAgentPreference` it set to `Custom user agent`.
-        customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
-        customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals("Custom user agent"));
-
-
-        // Set the Tor homepage URL as the summary text for the `tor_homepage` preference when the preference screen is loaded.  The default is DuckDuckGo: `https://3g2upl4pq6kufc4m.onion`.
-        torHomepagePreference.setSummary(savedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
+        // Set the summary text for the custom user agent preference.
+        customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
 
+        // Only enable the custom user agent preference if the user agent is set to `Custom`.
+        customUserAgentPreference.setEnabled(Objects.equals(userAgentPreference.getSummary(), getString(R.string.custom_user_agent)));
 
-        // Set the Tor search URL as the summary text for the Tor preference when the preference screen is loaded.  The default is `https://3g2upl4pq6kufc4m.onion/html/?q=`
-        if (torSearchString.equals("Custom URL")) {
+        // Set the search URL as the summary text for the search preference when the preference screen is loaded.
+        if (searchString.equals("Custom URL")) {
             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
-            torSearchPreference.setSummary(R.string.custom_url);
+            searchPreference.setSummary(R.string.custom_url);
         } else {
             // Set the array value as the summary text.
-            torSearchPreference.setSummary(torSearchString);
+            searchPreference.setSummary(searchString);
         }
 
-        // Set the summary text for `tor_search_custom_url`.  The default is `""`.
-        torSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_search_custom_url", ""));
+        // Set the summary text for the search custom URL (the default is `""`).
+        searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
 
-        // Enable the Tor custom URL search options only if proxying through Orbot and the search is set to `Custom URL`.
-        torSearchCustomURLPreference.setEnabled(proxyThroughOrbotBoolean && torSearchString.equals("Custom URL"));
+        // Only enable the search custom URL preference if the search is set to `Custom URL`.
+        searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
 
 
-        // Set the search URL as the summary text for the search preference when the preference screen is loaded.  The default is `https://duckduckgo.com/html/?q=`.
-        if (searchString.equals("Custom URL")) {
-            // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
-            searchPreference.setSummary(R.string.custom_url);
-        } else {
-            // Set the array value as the summary text.
-            searchPreference.setSummary(searchString);
+        // Set the summary text for the proxy preference when the preference screen is loaded.
+        switch (proxyString) {
+            case ProxyHelper.NONE:
+                proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
+                break;
+
+            case ProxyHelper.TOR:
+                proxyPreference.setSummary(getString(R.string.tor_enabled));
+                break;
+
+            case ProxyHelper.I2P:
+                proxyPreference.setSummary(getString(R.string.i2p_enabled));
+                break;
+
+            case ProxyHelper.CUSTOM:
+                proxyPreference.setSummary(getString(R.string.custom_proxy));
+                break;
         }
 
-        // Set the summary text for `search_custom_url` (the default is `""`) and enable it if `search` is set to `Custom URL`.
-        searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", ""));
-        searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
+        // Set the summary text for the custom proxy URL.
+        proxyCustomUrlPreference.setSummary(sharedPreferences.getString(getString(R.string.proxy_custom_url_key), getString(R.string.proxy_custom_url_default_value)));
 
+        // Only enable the custom proxy URL if a custom proxy is selected.
+        proxyCustomUrlPreference.setEnabled(proxyString.equals(ProxyHelper.CUSTOM));
 
-        // Enable `translucentNavigationBarPreference` only if full screen browsing mode is enabled and `hide_system_bars` is disabled.
-        translucentNavigationBarPreference.setEnabled(fullScreenBrowsingModeBoolean && !hideSystemBarsBoolean);
 
+        // Set the status of the clear and exit preferences.
+        clearCookiesPreference.setEnabled(!clearEverything);
+        clearDomStoragePreference.setEnabled(!clearEverything);
+        clearFormDataPreference.setEnabled(!clearEverything);  // The form data line can be removed once the minimum API is >= 26.
+        clearLogcatPreference.setEnabled(!clearEverything);
+        clearCachePreference.setEnabled(!clearEverything);
 
-        // Set the homepage URL as the summary text for the `Homepage` preference when the preference screen is loaded.  The default is `https://duckduckgo.com`.
-        homepagePreference.setSummary(savedPreferences.getString("homepage", "https://duckduckgo.com"));
 
-        // Set the default font size as the summary text for the `Default Font Size` preference when the preference screen is loaded.  The default is `100`.
-        defaultFontSizePreference.setSummary(savedPreferences.getString("default_font_size", "100") + "%%");
+        // Set the homepage URL as the summary text for the homepage preference.
+        homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
 
 
-        // Set the `javaScriptPreference` icon.
-        if (javaScriptEnabledBoolean) {
-            javaScriptPreference.setIcon(R.drawable.javascript_enabled);
-        } else {
-            javaScriptPreference.setIcon(R.drawable.privacy_mode);
+        // Set the font size as the summary text for the preference.
+        fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
+
+
+        // Get the app theme string arrays.
+        appThemeEntriesStringArray = resources.getStringArray(R.array.app_theme_entries);
+        appThemeEntryValuesStringArray = resources.getStringArray(R.array.app_theme_entry_values);
+
+        // Get the current app theme.
+        String currentAppTheme = sharedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
+
+        // Define an app theme entry number.
+        int appThemeEntryNumber;
+
+        // Get the app theme entry number that matches the current app theme.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
+        if (currentAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
+            // Store the app theme entry number.
+            appThemeEntryNumber = 1;
+        } else if (currentAppTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
+            // Store the app theme entry number.
+            appThemeEntryNumber = 2;
+        } else {  // The system default theme is selected.
+            // Store the app theme entry number.
+            appThemeEntryNumber = 0;
+        }
+
+        // Set the current theme as the summary text for the preference.
+        appThemePreference.setSummary(appThemeEntriesStringArray[appThemeEntryNumber]);
+
+
+        // Get the WebView theme string arrays.
+        webViewThemeEntriesStringArray = resources.getStringArray(R.array.webview_theme_entries);
+        webViewThemeEntryValuesStringArray = resources.getStringArray(R.array.webview_theme_entry_values);
+
+        // Get the current WebView theme.
+        String currentWebViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
+
+        // Define a WebView theme entry number.
+        int webViewThemeEntryNumber;
+
+        // Get the WebView theme entry number that matches the current WebView theme.  A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
+        if (currentWebViewTheme.equals(webViewThemeEntryValuesStringArray[1])) {  // The light theme is selected.
+            // Store the WebView theme entry number.
+            webViewThemeEntryNumber = 1;
+        } else if (currentWebViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
+            // Store the WebView theme entry number.
+            webViewThemeEntryNumber = 2;
+        } else {  // The system default theme is selected.
+            // Store the WebView theme entry number.
+            webViewThemeEntryNumber = 0;
         }
 
-        // Set the `firstPartyCookiesPreference` icon.
-        if (firstPartyCookiesEnabledBoolean) {
-            firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
+        // Set the current theme as the summary text for the preference.
+        webViewThemePreference.setSummary(webViewThemeEntriesStringArray[webViewThemeEntryNumber]);
+
+
+        // Set the JavaScript icon.
+        if (javaScriptEnabled) {
+            javaScriptPreference.setIcon(R.drawable.javascript_enabled);
         } else {
-            firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
+            javaScriptPreference.setIcon(R.drawable.privacy_mode);
         }
 
-        // Set the `thirdPartyCookiesPreference` icon.
-        if (firstPartyCookiesEnabledBoolean && Build.VERSION.SDK_INT >= 21) {
-            if (thirdPartyCookiesEnabledBoolean) {
-                thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
-            } else {
-                thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
-            }
+        // Set the cookies icon.
+        if (sharedPreferences.getBoolean(getString(R.string.cookies_key), false)) {
+            cookiesPreference.setIcon(R.drawable.cookies_enabled);
         } else {
-            thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted);
+            cookiesPreference.setIcon(R.drawable.cookies_disabled);
         }
 
-        // Set the `domStoragePreference` icon.
-        if (javaScriptEnabledBoolean) {
-            if (savedPreferences.getBoolean("dom_storage_enabled", false)) {
+        // Set the DOM storage icon.
+        if (javaScriptEnabled) {  // The preference is enabled.
+            if (sharedPreferences.getBoolean("dom_storage", false)) {  // DOM storage is enabled.
                 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
-            } else {
+            } else {  // DOM storage is disabled.
                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
             }
-        } else {
+        } else {  // The preference is disabled.  The icon should be ghosted.
             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted);
         }
 
-        // Set the `saveFormDataPreference` icon.
-        if (savedPreferences.getBoolean("save_form_data_enabled", false)) {
-            saveFormDataPreference.setIcon(R.drawable.form_data_enabled);
-        } else {
-            saveFormDataPreference.setIcon(R.drawable.form_data_disabled);
+        // Set the save form data icon if API < 26.  Save form data has no effect on API >= 26.
+        if (Build.VERSION.SDK_INT < 26) {
+            if (sharedPreferences.getBoolean("save_form_data", false)) {
+                formDataPreference.setIcon(R.drawable.form_data_enabled);
+            } else {
+                formDataPreference.setIcon(R.drawable.form_data_disabled);
+            }
         }
 
-        // Set the `customUserAgentPreference` icon.
+        // Set the custom user agent icon.
         if (customUserAgentPreference.isEnabled()) {
             customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled);
         } else {
             customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
         }
 
-        // Set the `blockAdsPreference` icon.
-        if (savedPreferences.getBoolean("block_ads", true)) {
-            blockAdsPreference.setIcon(R.drawable.block_ads_enabled);
+        // Set the incognito mode icon.
+        if (sharedPreferences.getBoolean("incognito_mode", false)) {
+            incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
         } else {
-            blockAdsPreference.setIcon(R.drawable.block_ads_disabled);
+            incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
         }
 
-        // Set the `incognitoModePreference` icon.
-        if (savedPreferences.getBoolean("incognito_mode", false)) {
-            incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
+        // Set the allow screenshots icon.
+        if (sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)) {
+            allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled);
         } else {
-            incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
+            allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled);
         }
 
-        // Set the `doNotTrackPreference` icon.
-        if (savedPreferences.getBoolean("do_not_track", false)) {
-            doNotTrackPreference.setIcon(R.drawable.do_not_track_enabled);
+        // Set the EasyList icon.
+        if (sharedPreferences.getBoolean("easylist", true)) {
+            easyListPreference.setIcon(R.drawable.block_ads_enabled);
         } else {
-            doNotTrackPreference.setIcon(R.drawable.do_not_track_disabled);
+            easyListPreference.setIcon(R.drawable.block_ads_disabled);
         }
 
-        // Set the `proxyThroughOrbotPreference` icon.
-        if (proxyThroughOrbotBoolean) {
-            proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled);
+        // Set the EasyPrivacy icon.
+        if (sharedPreferences.getBoolean("easyprivacy", true)) {
+            easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled);
         } else {
-            proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled);
+            easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled);
         }
 
-        // Set the `torSearchPreference` and `torSearchCustomURLPreference` icons.
-        if (proxyThroughOrbotBoolean) {
-            // Set the `torHomepagePreference` and `torSearchPreference` icons.
-            torHomepagePreference.setIcon(R.drawable.home_enabled);
-            torSearchPreference.setIcon(R.drawable.search_enabled);
+        // Set the Fanboy lists icons.
+        if (fanboyAnnoyanceListEnabled) {
+            // Set the Fanboy annoyance list icon.
+            fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled);
+
+            // Set the Fanboy social blocking list icon.
+            fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted);
+        } else {
+            // Set the Fanboy annoyance list icon.
+            fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled);
 
-            // Set the `torSearchCustomURLPreference` icon.
-            if (torSearchCustomURLPreference.isEnabled()) {
-                torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
+            // Set the Fanboy social blocking list icon.
+            if (fanboySocialBlockingEnabled) {
+                fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled);
             } else {
-                torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled);
+                fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled);
             }
-        } else {  // Proxy through Orbot is disabled.
-            torHomepagePreference.setIcon(R.drawable.home_ghosted);
-            torSearchPreference.setIcon(R.drawable.search_ghosted);
-            torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
         }
 
-        // Set the `searchCustomURLPreference` icon.
-        if (searchCustomURLPreference.isEnabled()) {
-            searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
+        // Set the UltraList icon.
+        if (sharedPreferences.getBoolean("ultralist", true)){
+            ultraListPreference.setIcon(R.drawable.block_ads_enabled);
         } else {
-            searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
+            ultraListPreference.setIcon(R.drawable.block_ads_disabled);
         }
 
-        // Set the full screen browsing mode icons.
-        if (fullScreenBrowsingModeBoolean) {
-            // Set the `fullScreenBrowsingModePreference` icon.
-            fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled);
+        // Set the UltraPrivacy icon.
+        if (sharedPreferences.getBoolean("ultraprivacy", true)) {
+            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled);
+        } else {
+            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled);
+        }
 
-            if (hideSystemBarsBoolean) {
-                // Set `hideSystemBarsPreference` to use the enabled icon.
-                hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled);
+        // Set the block all third-party requests icon.
+        if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
+            blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled);
+        } else {
+            blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled);
+        }
 
-                // Set `translucentNavigationBarPreference` to use the ghosted icon.
-                translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
-            } else {  // `hideSystemBarsBoolean` is false.
-                // Set `hideSystemBarsPreference` to use the disabled icon.
-                hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled);
+        // Set the Google Analytics icon.
+        if (sharedPreferences.getBoolean("google_analytics", true)) {
+            googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled);
+        } else {
+            googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled);
+        }
 
-                // Set the correct icon for `translucentNavigationBarPreference`.
-                if (savedPreferences.getBoolean("translucent_navigation_bar", true)) {
-                    translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
-                } else {
-                    translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
-                }
-            }
-        } else {  // `fullScreenBrwosingModeBoolean` is false.
-            fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled);
-            hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted);
-            translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
+        // Set the Facebook Click IDs icon.
+        if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
+            facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled);
+        } else {
+            facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled);
         }
 
-        // Set the `swipeToRefreshPreference` icon.
-        if (savedPreferences.getBoolean("swipe_to_refresh", false)) {
-            swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
+        // Set the Twitter AMP redirects icon.
+        if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
+            twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
         } else {
-            swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
+            twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
         }
 
-        // Set the `displayAdditionalAppBarIconsPreference` icon.
-        if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
-            displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled);
+        // Set the search custom URL icon.
+        if (searchCustomURLPreference.isEnabled()) {
+            searchCustomURLPreference.setIcon(R.drawable.search_custom_enabled);
         } else {
-            displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled);
+            searchCustomURLPreference.setIcon(R.drawable.search_custom_ghosted);
         }
 
-        // Listen for preference changes.
-        preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
-            @Override
-            // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.  We know.
-            @SuppressLint("SetJavaScriptEnabled")
-            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        // Set the Proxy icons according to the theme and status.
+        if (proxyString.equals(ProxyHelper.NONE)) {  // Proxying is disabled.
+            // Set the main proxy icon to be disabled.
+            proxyPreference.setIcon(R.drawable.proxy_disabled);
 
-                switch (key) {
-                    case "javascript_enabled":
-                        // Update the icons.
-                        if (sharedPreferences.getBoolean("javascript_enabled", false)) {
-                            // Update the icon for `javascript_enabled`.
-                            javaScriptPreference.setIcon(R.drawable.javascript_enabled);
+            // Set the custom proxy URL icon to be ghosted.
+            proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted);
+        } else {  // Proxying is enabled.
+            // Set the main proxy icon to be enabled.
+            proxyPreference.setIcon(R.drawable.proxy_enabled);
 
-                            // Update the icon for `dom_storage_enabled`.
-                            if (sharedPreferences.getBoolean("dom_storage_enabled", false)) {
-                                domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
-                            } else {
-                                domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
-                            }
-                        } else {  // `javascript_enabled` is `false`.
-                            // Update the icon for `javascript_enabled`.
-                            javaScriptPreference.setIcon(R.drawable.privacy_mode);
+            // Set the custom proxy URL icon according to its status.
+            if (proxyCustomUrlPreference.isEnabled()) {
+                proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled);
+            } else {
+                proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted);
+            }
+        }
 
-                            // Set the icon for `dom_storage_disabled` to be ghosted.
-                            domStoragePreference.setIcon(R.drawable.dom_storage_ghosted);
-                        }
-                        break;
-
-                    case "first_party_cookies_enabled":
-                        // Update the icons for `first_party_cookies_enabled` and `third_party_cookies_enabled`.
-                        if (sharedPreferences.getBoolean("first_party_cookies_enabled", false)) {
-                            // Set the icon for `first_party_cookies_enabled`.
-                            firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
-
-                            // Update the icon for `third_party_cookies_enabled`.
-                            if (Build.VERSION.SDK_INT >= 21) {
-                                if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) {
-                                    thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
-                                } else {
-                                    thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
-                                }
-                            } else {
-                                thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted);
-                            }
-                        } else {  // `first_party_cookies_enabled` is `false`.
-                            // Update the icon for `first_party_cookies_enabled`.
-                            firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
+        // Set the full screen browsing mode icons.
+        if (fullScreenBrowsingMode) {  // Full screen browsing mode is enabled.
+            // Set the full screen browsing mode preference icon.
+            fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled);
 
-                            // Set the icon for `third_party_cookies_enabled` to be ghosted.
-                            thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted);
-                        }
+            // Set the hide app bar icon.
+            if (sharedPreferences.getBoolean("hide_app_bar", true)) {
+                hideAppBarPreference.setIcon(R.drawable.app_bar_enabled);
+            } else {
+                hideAppBarPreference.setIcon(R.drawable.app_bar_disabled);
+            }
+        } else {  // Full screen browsing mode is disabled.
+            // Set the icons.
+            fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled);
+            hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted);
+        }
+
+        // Set the clear everything preference icon.
+        if (clearEverything) {
+            clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled);
+        } else {
+            clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
+        }
 
-                        // Enable `third_party_cookies_enabled` if `first_party_cookies_enabled` is `true` and API >= 21.
-                        thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false) && (Build.VERSION.SDK_INT >= 21));
-                        break;
+        // Set the clear cookies preference icon.
+        if (clearEverything || sharedPreferences.getBoolean("clear_cookies", true)) {
+            clearCookiesPreference.setIcon(R.drawable.clear_cookies_enabled);
+        } else {
+            clearCookiesPreference.setIcon(R.drawable.clear_cookies_disabled);
+        }
 
-                    case "third_party_cookies_enabled":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) {
-                            thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
-                        } else {
-                            thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
-                        }
-                        break;
+        // Set the clear DOM storage preference icon.
+        if (clearEverything || sharedPreferences.getBoolean("clear_dom_storage", true)) {
+            clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_enabled);
+        } else {
+            clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_disabled);
+        }
 
-                    case "dom_storage_enabled":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("dom_storage_enabled", false)) {
-                            domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
-                        } else {
-                            domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
-                        }
-                        break;
+        // Set the clear form data preference icon if the API < 26.  It has no effect on newer versions of Android.
+        if (Build.VERSION.SDK_INT < 26) {
+            if (clearEverything || sharedPreferences.getBoolean("clear_form_data", true)) {
+                clearFormDataPreference.setIcon(R.drawable.clear_form_data_enabled);
+            } else {
+                clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled);
+            }
+        }
 
-                    case "save_form_data_enabled":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("save_form_data_enabled", false)) {
-                            saveFormDataPreference.setIcon(R.drawable.form_data_enabled);
-                        } else {
-                            saveFormDataPreference.setIcon(R.drawable.form_data_disabled);
-                        }
+        // Set the clear logcat preference icon.
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_logcat_key), true)) {
+            clearLogcatPreference.setIcon(R.drawable.clear_logcat_enabled);
+        } else {
+            clearLogcatPreference.setIcon(R.drawable.clear_logcat_disabled);
+        }
 
-                    case "user_agent":
-                        String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0");
+        // Set the clear cache preference icon.
+        if (clearEverything || sharedPreferences.getBoolean("clear_cache", true)) {
+            clearCachePreference.setIcon(R.drawable.clear_cache_enabled);
+        } else {
+            clearCachePreference.setIcon(R.drawable.clear_cache_disabled);
+        }
 
-                        switch (userAgentString) {
-                            case "WebView default user agent":
-                                // Display the user agent as the summary text for `userAgentPreference`.
-                                userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
+        // Set the open intents in new tab preference icon.
+        if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
+            openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled);
+        } else {
+            openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled);
+        }
 
-                                // Update `customUserAgentPreference`.
-                                customUserAgentPreference.setEnabled(false);
-                                customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
-                                break;
+        // Set the swipe to refresh preference icon.
+        if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
+            swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
+        } else {
+            swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
+        }
 
-                            case "Custom user agent":
-                                // Display `Custom user agent` as the summary text for `userAgentPreference`.
-                                userAgentPreference.setSummary(R.string.custom_user_agent);
+        // Set the download with external app preference icon.
+        if (sharedPreferences.getBoolean(getString(R.string.download_with_external_app_key), false)) {
+            downloadWithExternalAppPreference.setIcon(R.drawable.download_with_external_app_enabled);
+        } else {
+            downloadWithExternalAppPreference.setIcon(R.drawable.download_with_external_app_disabled);
+        }
 
-                                // Update `customUserAgentPreference`.
-                                customUserAgentPreference.setEnabled(true);
-                                customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled);
-                                break;
+        // Set the scroll app bar preference icon.
+        if (sharedPreferences.getBoolean(getString(R.string.scroll_app_bar_key), true)) {
+            scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled);
+        } else {
+            scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled);
+        }
 
-                            default:
-                                // Display the user agent as the summary text for `userAgentPreference`.
-                                userAgentPreference.setSummary(sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
+        // Set the bottom app bar preference icon.
+        if (sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)) {
+            bottomAppBarPreference.setIcon(R.drawable.bottom_app_bar_enabled);
+        } else {
+            bottomAppBarPreference.setIcon(R.drawable.bottom_app_bar_disabled);
+        }
 
-                                // Update `customUserAgentPreference`.
-                                customUserAgentPreference.setEnabled(false);
-                                customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
-                                break;
-                        }
-                        break;
+        // Set the display additional app bar icons preference icon.
+        if (sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false)) {
+            displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled);
+        } else {
+            displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled);
+        }
 
-                    case "custom_user_agent":
-                        // Set the new custom user agent as the summary text for `custom_user_agent`.  The default is `PrivacyBrowser/1.0`.
-                        customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
-                        break;
+        // Set the WebView theme preference icon.
+        switch (webViewThemeEntryNumber) {
+            case 0:  // The system default WebView theme is selected.
+                // Set the icon according to the app theme.
+                if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
+                    webViewThemePreference.setIcon(R.drawable.webview_light_theme);
+                } else {
+                    webViewThemePreference.setIcon(R.drawable.webview_dark_theme);
+                }
+                break;
 
-                    case "block_ads":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("block_ads", true)) {
-                            blockAdsPreference.setIcon(R.drawable.block_ads_enabled);
-                        } else {
-                            blockAdsPreference.setIcon(R.drawable.block_ads_disabled);
-                        }
-                        break;
+            case 1:  // The light WebView theme is selected.
+                // Set the icon.
+                webViewThemePreference.setIcon(R.drawable.webview_light_theme);
+                break;
 
-                    case "incognito_mode":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("incognito_mode", false)) {
-                            incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
-                        } else {
-                            incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
-                        }
-                        break;
+            case 2:  // The dark WebView theme is selected.
+                // Set the icon.
+                webViewThemePreference.setIcon(R.drawable.webview_dark_theme);
+                break;
+        }
 
-                    case "do_not_track":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("do_not_track", false)) {
-                            doNotTrackPreference.setIcon(R.drawable.do_not_track_enabled);
-                        } else {
-                            doNotTrackPreference.setIcon(R.drawable.do_not_track_disabled);
-                        }
+        // Set the wide viewport preference icon.
+        if (sharedPreferences.getBoolean("wide_viewport", true)) {
+            wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled);
+        } else {
+            wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled);
+        }
 
-                        break;
+        // Set the display webpage images preference icon.
+        if (sharedPreferences.getBoolean("display_webpage_images", true)) {
+            displayWebpageImagesPreference.setIcon(R.drawable.images_enabled);
+        } else {
+            displayWebpageImagesPreference.setIcon(R.drawable.images_disabled);
+        }
+    }
 
-                    case "proxy_through_orbot":
-                        // Get current settings.
-                        boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
-                        String currentTorSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
+    // The listener should be unregistered when the app is paused.
+    @Override
+    public void onPause() {
+        // Run the default commands.
+        super.onPause();
 
-                        // Enable the Tor custom URL search option only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`.
-                        torSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorSearchString.equals("Custom URL"));
+        // Get a handle for the shared preferences.
+        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
 
-                        // Update the icons.
-                        if (currentProxyThroughOrbot) {
-                            // Set the `proxyThroughOrbotPreference`, `torHomepagePreference`, and `torSearchPreference` icons.
-                            proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled);
-                            torHomepagePreference.setIcon(R.drawable.home_enabled);
-                            torSearchPreference.setIcon(R.drawable.search_enabled);
-
-                            // Set the `torSearchCustomURLPreference` icon.
-                            if (torSearchCustomURLPreference.isEnabled()) {
-                                torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
-                            } else {
-                                torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled);
-                            }
-                        } else {  // Proxy through Orbot is disabled.
-                            proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled);
-                            torHomepagePreference.setIcon(R.drawable.home_ghosted);
-                            torSearchPreference.setIcon(R.drawable.search_ghosted);
-                            torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
-                        }
-                        break;
+        // Remove the incorrect lint warning below that the shared preferences might be null.
+        assert sharedPreferences != null;
 
-                    case "tor_homepage":
-                        // Set the new tor homepage URL as the summary text for the `tor_homepage` preference.  The default is DuckDuckGo:  `https://3g2upl4pq6kufc4m.onion`.
-                        torHomepagePreference.setSummary(sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
-                        break;
+        // Unregister the shared preference listener.
+        sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
+    }
 
-                    case "tor_search":
-                        // Get the present search string.
-                        String presentTorSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
+    // The listener should be re-registered when the app is resumed.
+    @Override
+    public void onResume() {
+        // Run the default commands.
+        super.onResume();
 
-                        // Update the preferences.
-                        if (presentTorSearchString.equals("Custom URL")) {
-                            // Use `R.string.custom_url`, which is translated, as the summary instead of the array value, which isn't.
-                            torSearchPreference.setSummary(R.string.custom_url);
+        // Get a new shared preference change listener.
+        sharedPreferenceChangeListener = getSharedPreferenceChangeListener(requireContext());
 
-                            // Update `torSearchCustomURLPreference`.
-                            torSearchCustomURLPreference.setEnabled(true);
-                            torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
-                        } else {
-                            // Set the array value as the summary text.
-                            torSearchPreference.setSummary(presentTorSearchString);
+        // Get a handle for the shared preferences.
+        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
 
-                            // Update `torSearchCustomURLPreference`.
-                            torSearchCustomURLPreference.setEnabled(false);
-                            torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled);
-                        }
-                        break;
-
-                    case "tor_search_custom_url":
-                        // Set the summary text for `tor_search_custom_url`.
-                        torSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_search_custom_url", ""));
-                        break;
-
-                    case "search":
-                        // Store the new search string.
-                        String newSearchString = sharedPreferences.getString("search", "https://duckduckgo.com/html/?q=");
-
-                        // Update `searchPreference` and `searchCustomURLPreference`.
-                        if (newSearchString.equals("Custom URL")) {  // `Custom URL` is selected.
-                            // Set the summary text to `R.string.custom_url`, which is translated.
-                            searchPreference.setSummary(R.string.custom_url);
-
-                            // Update `searchCustomURLPreference`.
-                            searchCustomURLPreference.setEnabled(true);
-                            searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
-                        } else {  // `Custom URL` is not selected.
-                            // Set the summary text to `newSearchString`.
-                            searchPreference.setSummary(newSearchString);
-
-                            // Update `searchCustomURLPreference`.
-                            searchCustomURLPreference.setEnabled(false);
-                            searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
-                        }
-                        break;
-
-                    case "search_custom_url":
-                        // Set the new custom search URL as the summary text for `search_custom_url`.  The default is `""`.
-                        searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", ""));
-                        break;
-
-                    case "full_screen_browsing_mode":
-                        if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) {
-                            // Set `fullScreenBrowsingModePreference` to use the enabled icon.
-                            fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled);
-
-                            if (sharedPreferences.getBoolean("hide_system_bars", false)) {
-                                // Set `hideSystemBarsPreference` to use the enabled icon.
-                                hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled);
-
-                                // Update `translucentNavigationBarPreference`.
-                                translucentNavigationBarPreference.setEnabled(false);
-                                translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
-                            } else {  // `hide_system_bars` is false.
-                                // Set `hideSystemBarsPreference` to use the disabled icon.
-                                hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled);
-
-                                // Update `translucentNavigationBarPreference`.
-                                translucentNavigationBarPreference.setEnabled(true);
-                                if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) {
-                                    translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
-                                } else {
-                                    translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
-                                }
-                            }
-                        } else {  // `full_screen_browsing_mode` is false.
-                            // Disable `translucentNavigationBarPreference`.
-                            translucentNavigationBarPreference.setEnabled(false);
-
-                            // Update the icons.
-                            fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled);
-                            hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted);
-                            translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
+        // Remove the incorrect lint warning below that the shared preferences might be null.
+        assert sharedPreferences != null;
+
+        // Re-register the shared preference listener.
+        sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
+    }
+
+    // The context must be passed to the shared preference change listener or else any calls to the system `getString()` will crash if the app has been restarted.
+    // This can be removed at some future point, perhaps after the switch to PreferenceScreenCompat.  It isn't an issue in Privacy Cell.
+    private SharedPreferences.OnSharedPreferenceChangeListener getSharedPreferenceChangeListener(Context context) {
+        // Return the shared preference change listener.
+        return (SharedPreferences sharedPreferences, String key) -> {
+            switch (key) {
+                case "javascript":
+                    // Update the icons and the DOM storage preference status.
+                    if (sharedPreferences.getBoolean("javascript", false)) {  // The JavaScript preference is enabled.
+                        // Update the icon for the JavaScript preference.
+                        javaScriptPreference.setIcon(R.drawable.javascript_enabled);
+
+                        // Update the status of the DOM storage preference.
+                        domStoragePreference.setEnabled(true);
+
+                        // Update the icon for the DOM storage preference.
+                        if (sharedPreferences.getBoolean("dom_storage", false)) {
+                            domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
+                        } else {
+                            domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
                         }
-                        break;
-
-                    case "hide_system_bars":
-                        if (sharedPreferences.getBoolean("hide_system_bars", false)) {
-                            // Set `hideSystemBarsPreference` to use the enabled icon.
-                            hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled);
-
-                            // Update `translucentNavigationBarPreference`.
-                            translucentNavigationBarPreference.setEnabled(false);
-                            translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
-                        } else {  // `hide_system_bars` is false.
-                            // Set `hideSystemBarsPreference` to use the disabled icon.
-                            hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled);
-
-                            // Update `translucentNavigationBarPreference`.
-                            translucentNavigationBarPreference.setEnabled(true);
-                            if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) {
-                                translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
-                            } else {
-                                translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
-                            }
+                    } else {  // The JavaScript preference is disabled.
+                        // Update the icon for the JavaScript preference.
+                        javaScriptPreference.setIcon(R.drawable.privacy_mode);
+
+                        // Update the status of the DOM storage preference.
+                        domStoragePreference.setEnabled(false);
+
+                        // Set the icon for DOM storage preference to be ghosted.
+                        domStoragePreference.setIcon(R.drawable.dom_storage_ghosted);
+                    }
+                    break;
+
+                case "cookies":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.cookies_key), false)) {
+                        cookiesPreference.setIcon(R.drawable.cookies_enabled);
+                    } else {
+                        cookiesPreference.setIcon(R.drawable.cookies_disabled);
+                    }
+                    break;
+
+                case "dom_storage":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("dom_storage", false)) {
+                        domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
+                    } else {
+                        domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
+                    }
+                    break;
+
+                // Save form data can be removed once the minimum API >= 26.
+                case "save_form_data":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("save_form_data", false)) {
+                        formDataPreference.setIcon(R.drawable.form_data_enabled);
+                    } else {
+                        formDataPreference.setIcon(R.drawable.form_data_disabled);
+                    }
+                    break;
+
+                case "user_agent":
+                    // Get the new user agent name.
+                    String newUserAgentName = sharedPreferences.getString("user_agent", context.getString(R.string.user_agent_default_value));
+
+                    // Get the array position for the new user agent name.
+                    int newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName);
+
+                    // Get the translated new user agent name.
+                    String translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition];
+
+                    // Populate the user agent summary.
+                    switch (newUserAgentArrayPosition) {
+                        case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
+                            // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
+                            userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + defaultUserAgent);
+
+                            // Disable the custom user agent preference.
+                            customUserAgentPreference.setEnabled(false);
+
+                            // Set the custom user agent preference icon.
+                            customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
+                            break;
+
+                        case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
+                            // Set the summary text.
+                            userAgentPreference.setSummary(R.string.custom_user_agent);
+
+                            // Enable the custom user agent preference.
+                            customUserAgentPreference.setEnabled(true);
+
+                            // Set the custom user agent preference icon.
+                            customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled);
+                            break;
+
+                        default:
+                            // Get the user agent summary from the user agent data array.
+                            userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + userAgentDataArray[newUserAgentArrayPosition]);
+
+                            // Disable the custom user agent preference.
+                            customUserAgentPreference.setEnabled(false);
+
+                            // Set the custom user agent preference icon.
+                            customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
+                    }
+                    break;
+
+                case "custom_user_agent":
+                    // Set the new custom user agent as the summary text for the preference.
+                    customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", context.getString(R.string.custom_user_agent_default_value)));
+                    break;
+
+                case "incognito_mode":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("incognito_mode", false)) {
+                        incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
+                    } else {
+                        incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
+                    }
+                    break;
+
+                case "allow_screenshots":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.allow_screenshots_key), false)) {
+                        allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled);
+                    } else {
+                        allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled);
+                    }
+
+                    // Restart Privacy Browser.
+                    restartPrivacyBrowser();
+                    break;
+
+                case "easylist":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("easylist", true)) {
+                        easyListPreference.setIcon(R.drawable.block_ads_enabled);
+                    } else {
+                        easyListPreference.setIcon(R.drawable.block_ads_disabled);
+                    }
+                    break;
+
+                case "easyprivacy":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("easyprivacy", true)) {
+                        easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled);
+                    } else {
+                        easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled);
+                    }
+                    break;
+
+                case "fanboys_annoyance_list":
+                    boolean currentFanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
+                    boolean currentFanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
+
+                    // Update the Fanboy icons.
+                    if (currentFanboyAnnoyanceList) {  // Fanboy's annoyance list is enabled.
+                        // Update the Fanboy's annoyance list icon.
+                        fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled);
+
+                        // Update the Fanboy's social blocking list icon.
+                        fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted);
+                    } else {  // Fanboy's annoyance list is disabled.
+                        // Update the Fanboy's annoyance list icon.
+                        fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled);
+
+                        // Update the Fanboy's social blocking list icon.
+                        if (currentFanboySocialBlockingList) {
+                            fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled);
+                        } else {
+                            fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled);
                         }
-                        break;
-
-                    case "translucent_navigation_bar":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) {
-                            translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
+                    }
+
+                    // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
+                    fanboySocialBlockingListPreference.setEnabled(!currentFanboyAnnoyanceList);
+                    break;
+
+                case "fanboys_social_blocking_list":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("fanboys_social_blocking_list", true)) {
+                        fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled);
+                    } else {
+                        fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled);
+                    }
+                    break;
+
+                case "ultralist":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("ultralist", true)) {
+                        ultraListPreference.setIcon(R.drawable.block_ads_enabled);
+                    } else {
+                        ultraListPreference.setIcon(R.drawable.block_ads_disabled);
+                    }
+                    break;
+
+                case "ultraprivacy":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("ultraprivacy", true)) {
+                        ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled);
+                    } else {
+                        ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled);
+                    }
+                    break;
+
+                case "block_all_third_party_requests":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
+                        blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled);
+                    } else {
+                        blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled);
+                    }
+                    break;
+
+                case "google_analytics":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("google_analytics", true)) {
+                        googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled);
+                    } else {
+                        googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled);
+                    }
+                    break;
+
+                case "facebook_click_ids":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
+                        facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled);
+                    } else {
+                        facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled);
+                    }
+                    break;
+
+                case "twitter_amp_redirects":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
+                        twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
+                    } else {
+                        twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
+                    }
+                    break;
+
+                case "search":
+                    // Store the new search string.
+                    String newSearchString = sharedPreferences.getString("search", context.getString(R.string.search_default_value));
+
+                    // Update the search and search custom URL preferences.
+                    if (newSearchString.equals("Custom URL")) {  // `Custom URL` is selected.
+                        // Set the summary text to `R.string.custom_url`, which is translated.
+                        searchPreference.setSummary(R.string.custom_url);
+
+                        // Enable the search custom URL preference.
+                        searchCustomURLPreference.setEnabled(true);
+
+                        // Set the search custom URL preference icon.
+                        searchCustomURLPreference.setIcon(R.drawable.search_custom_enabled);
+                    } else {  // `Custom URL` is not selected.
+                        // Set the summary text to `newSearchString`.
+                        searchPreference.setSummary(newSearchString);
+
+                        // Disable `searchCustomURLPreference`.
+                        searchCustomURLPreference.setEnabled(false);
+
+                        // Set the search custom URL preference icon.
+                        searchCustomURLPreference.setIcon(R.drawable.search_custom_ghosted);
+                    }
+                    break;
+
+                case "search_custom_url":
+                    // Set the new search custom URL as the summary text for the preference.
+                    searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", context.getString(R.string.search_custom_url_default_value)));
+                    break;
+
+                case "proxy":
+                    // Get current proxy string.
+                    String currentProxyString = sharedPreferences.getString("proxy", context.getString(R.string.proxy_default_value));
+
+                    // Update the summary text for the proxy preference.
+                    switch (currentProxyString) {
+                        case ProxyHelper.NONE:
+                            proxyPreference.setSummary(context.getString(R.string.no_proxy_enabled));
+                            break;
+
+                        case ProxyHelper.TOR:
+                            proxyPreference.setSummary(context.getString(R.string.tor_enabled));
+                            break;
+
+                        case ProxyHelper.I2P:
+                            proxyPreference.setSummary(context.getString(R.string.i2p_enabled));
+                            break;
+
+                        case ProxyHelper.CUSTOM:
+                            proxyPreference.setSummary(context.getString(R.string.custom_proxy));
+                            break;
+                    }
+
+                    // Update the status of the custom URL preference.
+                    proxyCustomUrlPreference.setEnabled(currentProxyString.equals(ProxyHelper.CUSTOM));
+
+                    // Update the icons.
+                    if (currentProxyString.equals(ProxyHelper.NONE)) {  // Proxying is disabled.
+                        // Set the main proxy icon to be disabled
+                        proxyPreference.setIcon(R.drawable.proxy_disabled);
+
+                        // Set the custom proxy URL icon to be ghosted.
+                        proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted);
+                    } else {  // Proxying is enabled.
+                        // Set the main proxy icon to be enabled.
+                        proxyPreference.setIcon(R.drawable.proxy_enabled);
+
+                        /// Set the custom proxy URL icon according to its status.
+                        if (proxyCustomUrlPreference.isEnabled()) {
+                            proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled);
                         } else {
-                            translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
+                            proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted);
                         }
-                        break;
-
-                    case "homepage":
-                        // Set the new homepage URL as the summary text for the Homepage preference.  The default is `https://www.duckduckgo.com`.
-                        homepagePreference.setSummary(sharedPreferences.getString("homepage", "https://www.duckduckgo.com"));
-                        break;
-
-                    case "default_font_size":
-                        // Update the summary text of `default_font_size`.
-                        defaultFontSizePreference.setSummary(sharedPreferences.getString("default_font_size", "100") + "%%");
-                        break;
-
-                    case "swipe_to_refresh":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("swipe_to_refresh", false)) {
-                            swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
+                    }
+                    break;
+
+                case "proxy_custom_url":
+                    // Set the summary text for the proxy custom URL.
+                    proxyCustomUrlPreference.setSummary(sharedPreferences.getString(context.getString(R.string.proxy_custom_url_key), context.getString(R.string.proxy_custom_url_default_value)));
+                    break;
+
+                case "full_screen_browsing_mode":
+                    if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) {  // Full screen browsing is enabled.
+                        // Set the full screen browsing mode preference icon.
+                        fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled);
+
+                        // Set the hide app bar preference icon.
+                        if (sharedPreferences.getBoolean("hide_app_bar", true)) {
+                            hideAppBarPreference.setIcon(R.drawable.app_bar_enabled);
                         } else {
-                            swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
+                            hideAppBarPreference.setIcon(R.drawable.app_bar_disabled);
                         }
-                        break;
-
-                    case "display_additional_app_bar_icons":
-                        // Update the icon.
-                        if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
-                            displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled);
+                    } else {  // Full screen browsing is disabled.
+                        // Update the icons.
+                        fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled);
+                        hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted);
+                    }
+                    break;
+
+                case "hide_app_bar":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("hide_app_bar", true)) {
+                        hideAppBarPreference.setIcon(R.drawable.app_bar_enabled);
+                    } else {  // Hide app bar is disabled.
+                        // Set the icon according to the theme.
+                        hideAppBarPreference.setIcon(R.drawable.app_bar_disabled);
+                    }
+                    break;
+
+                case "clear_everything":
+                    // Store the new clear everything status
+                    boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
+
+                    // Update the status of the clear and exit preferences.
+                    clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
+                    clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
+                    clearFormDataPreference.setEnabled(!newClearEverythingBoolean);  // This line can be removed once the minimum API >= 26.
+                    clearLogcatPreference.setEnabled(!newClearEverythingBoolean);
+                    clearCachePreference.setEnabled(!newClearEverythingBoolean);
+
+                    // Update the clear everything preference icon.
+                    if (newClearEverythingBoolean) {
+                        clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled);
+                    } else {
+                        clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
+                    }
+
+                    // Update the clear cookies preference icon.
+                    if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
+                        clearCookiesPreference.setIcon(R.drawable.clear_cookies_enabled);
+                    } else {
+                        clearCookiesPreference.setIcon(R.drawable.clear_cookies_disabled);
+                    }
+
+                    // Update the clear dom storage preference icon.
+                    if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
+                        clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_enabled);
+                    } else {
+                        clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_disabled);
+                    }
+
+                    // Update the clear form data preference icon if the API < 26.
+                    if (Build.VERSION.SDK_INT < 26) {
+                        if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
+                            clearFormDataPreference.setIcon(R.drawable.clear_form_data_enabled);
                         } else {
-                            displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled);
+                            clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled);
                         }
-                        break;
-
-                    default:
-                        // If no match, do nothing.
-                        break;
-                }
+                    }
+
+                    // Update the clear logcat preference icon.
+                    if (newClearEverythingBoolean || sharedPreferences.getBoolean(context.getString(R.string.clear_logcat_key), true)) {
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_enabled);
+                    } else {
+                        clearLogcatPreference.setIcon(R.drawable.clear_cache_disabled);
+                    }
+
+                    // Update the clear cache preference icon.
+                    if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
+                        clearCachePreference.setIcon(R.drawable.clear_cache_enabled);
+                    } else {
+                        clearCachePreference.setIcon(R.drawable.clear_cache_disabled);
+                    }
+                    break;
+
+                case "clear_cookies":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("clear_cookies", true)) {
+                        clearCookiesPreference.setIcon(R.drawable.clear_cookies_enabled);
+                    } else {
+                        clearCookiesPreference.setIcon(R.drawable.clear_cookies_disabled);
+                    }
+                    break;
+
+                case "clear_dom_storage":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
+                        clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_enabled);
+                    } else {
+                        clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_disabled);
+                    }
+                    break;
+
+                // This section can be removed once the minimum API >= 26.
+                case "clear_form_data":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("clear_form_data", true)) {
+                        clearFormDataPreference.setIcon(R.drawable.clear_form_data_enabled);
+                    } else {
+                        clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled);
+                    }
+                    break;
+
+                case "clear_logcat":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.clear_logcat_key), true)) {
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_enabled);
+                    } else {
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_disabled);
+                    }
+                    break;
+
+                case "clear_cache":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("clear_cache", true)) {
+                        clearCachePreference.setIcon(R.drawable.clear_cache_enabled);
+                    } else {
+                        clearCachePreference.setIcon(R.drawable.clear_cache_disabled);
+                    }
+                    break;
+
+                case "homepage":
+                    // Set the new homepage URL as the summary text for the Homepage preference.
+                    homepagePreference.setSummary(sharedPreferences.getString("homepage", context.getString(R.string.homepage_default_value)));
+                    break;
+
+                case "font_size":
+                    // Update the font size summary text.
+                    fontSizePreference.setSummary(sharedPreferences.getString("font_size", context.getString(R.string.font_size_default_value)) + "%");
+                    break;
+
+                case "open_intents_in_new_tab":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
+                        openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled);
+                    } else {
+                        openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled);
+                    }
+                    break;
+
+                case "swipe_to_refresh":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
+                        swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
+                    } else {
+                        swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
+                    }
+                    break;
+
+                case "download_with_external_app":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.download_with_external_app_key), false)) {
+                        downloadWithExternalAppPreference.setIcon(R.drawable.download_with_external_app_enabled);
+                    } else {
+                        downloadWithExternalAppPreference.setIcon(R.drawable.download_with_external_app_disabled);
+                    }
+                    break;
+
+                case "scroll_app_bar":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.scroll_app_bar_key), true)) {
+                        scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled);
+                    } else {
+                        scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled);
+                    }
+                    break;
+
+                case "bottom_app_bar":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.bottom_app_bar_key), false)) {
+                        bottomAppBarPreference.setIcon(R.drawable.bottom_app_bar_enabled);
+                    } else {
+                        bottomAppBarPreference.setIcon(R.drawable.bottom_app_bar_disabled);
+                    }
+
+                    // Restart Privacy Browser.
+                    restartPrivacyBrowser();
+                    break;
+
+                case "display_additional_app_bar_icons":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(context.getString(R.string.display_additional_app_bar_icons_key), false)) {
+                        displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled);
+                    } else {
+                        displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled);
+                    }
+                    break;
+
+                case "app_theme":
+                    // Get the new theme.
+                    String newAppTheme = sharedPreferences.getString("app_theme", context.getString(R.string.app_theme_default_value));
+
+                    // Update the system according to the new theme.  A switch statement cannot be used because the theme entry values string array is not a compile-time constant.
+                    if (newAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
+                        // Update the theme preference summary text.
+                        appThemePreference.setSummary(appThemeEntriesStringArray[1]);
+
+                        // Apply the new theme.
+                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
+                    } else if (newAppTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
+                        // Update the theme preference summary text.
+                        appThemePreference.setSummary(appThemeEntriesStringArray[2]);
+
+                        // Apply the new theme.
+                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
+                    } else {  // The system default theme is selected.
+                        // Update the theme preference summary text.
+                        appThemePreference.setSummary(appThemeEntriesStringArray[0]);
+
+                        // Apply the new theme.
+                        if (Build.VERSION.SDK_INT >= 28) {  // The system default theme is supported.
+                            // Follow the system default theme.
+                            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
+                        } else {// The system default theme is not supported.
+                            // Follow the battery saver mode.
+                            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
+                        }
+                    }
+
+                    // Update the current theme status.
+                    currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+                    break;
+
+                case "webview_theme":
+                    // Get the new WebView theme.
+                    String newWebViewTheme = sharedPreferences.getString("webview_theme", context.getString(R.string.webview_theme_default_value));
+
+                    // Define a new WebView theme entry number.
+                    int newWebViewThemeEntryNumber;
+
+                    // Get the webView theme entry number that matches the new WebView theme.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
+                    if (newWebViewTheme.equals(webViewThemeEntriesStringArray[1])) {  // The light theme is selected.
+                        // Store the new WebView theme entry number.
+                        newWebViewThemeEntryNumber = 1;
+                    } else if (newWebViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
+                        // Store the WebView theme entry number.
+                        newWebViewThemeEntryNumber = 2;
+                    } else {  // The system default theme is selected.
+                        // Store the WebView theme entry number.
+                        newWebViewThemeEntryNumber = 0;
+                    }
+
+                    // Update the icon.
+                    switch (newWebViewThemeEntryNumber) {
+                        case 0:  // The system default WebView theme is selected.
+                            // Set the icon.
+                            if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
+                                webViewThemePreference.setIcon(R.drawable.webview_light_theme);
+                            } else {
+                                webViewThemePreference.setIcon(R.drawable.webview_dark_theme);
+                            }
+                            break;
+
+                        case 1:  // The light theme is selected.
+                            // Set the icon.
+                            webViewThemePreference.setIcon(R.drawable.webview_light_theme);
+                            break;
+
+                        case 2:  // The dark theme is selected.
+                            // Set the icon.
+                            webViewThemePreference.setIcon(R.drawable.webview_dark_theme);
+                            break;
+                    }
+
+                    // Set the current theme as the summary text for the preference.
+                    webViewThemePreference.setSummary(webViewThemeEntriesStringArray[newWebViewThemeEntryNumber]);
+                    break;
+
+                case "wide_viewport":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("wide_viewport", true)) {
+                        wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled);
+                    } else {
+                        wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled);
+                    }
+                    break;
+
+                case "display_webpage_images":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("display_webpage_images", true)) {
+                        displayWebpageImagesPreference.setIcon(R.drawable.images_enabled);
+                    } else {
+                        displayWebpageImagesPreference.setIcon(R.drawable.images_disabled);
+                    }
+                    break;
             }
         };
-
-        // Register the listener.
-        savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
     }
 
-    // It is necessary to re-register the listener on every resume or it will randomly stop working because apps can be paused and resumed at any time
-    // even while running in the foreground.
-    @Override
-    public void onPause() {
-        super.onPause();
-        savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
-    }
+    private void restartPrivacyBrowser() {
+        // Create an intent to restart Privacy Browser.
+        Intent restartIntent = requireActivity().getParentActivityIntent();
 
-    @Override
-    public void onResume() {
-        super.onResume();
-        savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
+        // Assert that the intent is not null to remove the lint error below.
+        assert restartIntent != null;
+
+        // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack.  It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
+        restartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+        // Create a handler to restart the activity.
+        Handler restartHandler = new Handler(Looper.getMainLooper());
+
+        // Create a runnable to restart the activity.
+        Runnable restartRunnable = () -> {
+            // Restart the activity.
+            startActivity(restartIntent);
+
+            // Kill this instance of Privacy Browser.  Otherwise, the app exhibits sporadic behavior after the restart.
+            System.exit(0);
+        };
+
+        // Restart the activity after 400 milliseconds, so that the app has enough time to save the change to the preference.
+        restartHandler.postDelayed(restartRunnable, 400);
     }
 }