]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/commitdiff
Add a bottom app bar to Settings. https://redmine.stoutner.com/issues/716
authorSoren Stoutner <soren@stoutner.com>
Wed, 26 Oct 2022 00:51:38 +0000 (17:51 -0700)
committerSoren Stoutner <soren@stoutner.com>
Wed, 26 Oct 2022 00:51:38 +0000 (17:51 -0700)
27 files changed:
app/src/main/AndroidManifest.xml
app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.kt
app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.kt
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java [deleted file]
app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.kt [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/dialogs/AddDomainDialog.kt
app/src/main/java/com/stoutner/privacybrowser/fragments/AboutVersionFragment.kt
app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java [deleted file]
app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.kt [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.kt
app/src/main/res/layout/save_dialog.xml
app/src/main/res/layout/settings_bottom_appbar.xml [new file with mode: 0644]
app/src/main/res/layout/settings_top_appbar.xml [new file with mode: 0644]
app/src/main/res/values-de/strings.xml
app/src/main/res/values-es/strings.xml
app/src/main/res/values-fr/strings.xml
app/src/main/res/values-it/strings.xml
app/src/main/res/values-night-v27/styles.xml
app/src/main/res/values-night/styles.xml
app/src/main/res/values-pt-rBR/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-tr/strings.xml
app/src/main/res/values-v27/styles.xml
app/src/main/res/values/strings.xml
app/src/main/res/values/styles.xml
app/src/main/res/xml/preferences.xml

index 0dbae9b6c0f085b355b3f87b0807ca40ab40567a..cc2645dd84fde815a6df5ec11100fc295428c20e 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2015-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -30,7 +30,6 @@
     <!-- Required to create home screen shortcuts. -->
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
 
-
     <!-- Support Chromebooks that don't have a touch screen. -->
     <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
 
@@ -94,8 +93,7 @@
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
             `android:launchMode="singleTask"` makes the app launch in a new task instead of inside the task of the program that sends it an intent.
             It also makes it reuse an existing Privacy Browser activity if available instead of launching a new one.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.MainWebViewActivity"
             android:label="@string/short_name"
             android:launchMode="singleTask"
             android:screenOrientation="fullUser"
             android:persistableMode="persistNever"
-            android:exported="true"
-            tools:ignore="UnusedAttribute" >
+            android:exported="true" >
 
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
         <!-- BookmarksActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.BookmarksActivity"
             android:label="@string/bookmarks"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- BookmarksDatabaseViewActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.BookmarksDatabaseViewActivity"
             android:label="@string/bookmarks_database_view"
             android:parentActivityName=".activities.BookmarksActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- RequestsActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.RequestsActivity"
             android:label="@string/requests"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- DomainsActivity.  `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not reload when a bluetooth keyboard is activated/goes to sleep.
             `android:windowSoftInputMode="stateAlwaysHidden"` keeps the keyboard from displaying when the screen is rotated and after the `AddDomainDialog` is dismissed.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.DomainsActivity"
             android:label="@string/domains"
             android:configChanges="screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
             android:windowSoftInputMode="stateAlwaysHidden"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- SettingsActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.SettingsActivity"
             android:label="@string/settings"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            android:theme="@style/PrivacyBrowserSettings"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- ImportExportActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.ImportExportActivity"
             android:label="@string/import_export"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- LogcatActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.LogcatActivity"
             android:label="@string/logcat"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- GuideActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.GuideActivity"
             android:label="@string/guide"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- AboutActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.AboutActivity"
             android:label="@string/about_privacy_browser"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
 
         <!-- ViewSourceActivity.  `android:configChanges="orientation|screenSize"` makes the activity not restart when the orientation changes, which preserves scroll location in the WebView.
             `android:configChanges="screenLayout"` makes the activity not restart when entering or exiting split screen mode.
             `android:configChanges="keyboard|keyboardHidden"` makes the activity not restart when a bluetooth keyboard is activated/goes to sleep.
-            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot.
-            `tools:ignore="unusedAttribute"` removes the lint warning that `persistableMode` does not apply to API < 21. -->
+            `android:persistableMode="persistNever"` removes Privacy Browser from the recent apps list on a device reboot. -->
         <activity
             android:name=".activities.ViewSourceActivity"
             android:label="@string/view_source"
             android:parentActivityName=".activities.MainWebViewActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
             android:screenOrientation="fullUser"
-            android:persistableMode="persistNever"
-            tools:ignore="UnusedAttribute" />
+            android:persistableMode="persistNever" />
     </application>
 </manifest>
index 0e1f320de1d20f87fec89ece6ac1b575ea2c5557..72e50c4c827404da022ff8eca10830afd63395f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2016-2022 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
  *
index 949b678a90e06cd325072b97dc0618d02a8ed818..2edab5528e915fef5231edebbf5bf880f6e50f58 100644 (file)
@@ -205,9 +205,6 @@ class DomainsActivity : AppCompatActivity(), AddDomainListener, DismissSnackbarI
             addDomainDialog.show(supportFragmentManager, resources.getString(R.string.add_domain))
         }
 
-        // Get a handle for the activity.
-        val activity: Activity = this
-
         // Control what the navigation bar back button does.
         val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
             override fun handleOnBackPressed() {
@@ -225,14 +222,14 @@ class DomainsActivity : AppCompatActivity(), AddDomainListener, DismissSnackbarI
                         undoDeleteSnackbar!!.dismiss()
                     } else {
                         // Go home.
-                        NavUtils.navigateUpFromSameTask(activity)
+                        finish()
                     }
                 } else if (closeOnBack) {  // Go directly back to the main WebView activity because the domains activity was launched from the options menu.
                     // Save the current domain settings.
                     saveDomainSettings(coordinatorLayout)
 
                     // Go home.
-                    NavUtils.navigateUpFromSameTask(activity)
+                    finish()
                 } else if (findViewById<View?>(R.id.domain_settings_scrollview) != null) {  // The device is in single-paned mode and domain settings fragment is displayed.
                     // Save the current domain settings.
                     saveDomainSettings(coordinatorLayout)
@@ -261,7 +258,7 @@ class DomainsActivity : AppCompatActivity(), AddDomainListener, DismissSnackbarI
                         undoDeleteSnackbar!!.dismiss()
                     } else {
                         // Go home.
-                        NavUtils.navigateUpFromSameTask(activity)
+                        finish()
                     }
                 }
             }
@@ -394,14 +391,14 @@ class DomainsActivity : AppCompatActivity(), AddDomainListener, DismissSnackbarI
                         undoDeleteSnackbar!!.dismiss()
                     } else {
                         // Go home.
-                        NavUtils.navigateUpFromSameTask(this)
+                        finish()
                     }
                 } else if (closeOnBack) {  // Go directly back to the main WebView activity because the domains activity was launched from the options menu.
                     // Save the current domain settings.
                     saveDomainSettings(coordinatorLayout)
 
                     // Go home.
-                    NavUtils.navigateUpFromSameTask(this)
+                    finish()
                 } else if (findViewById<View?>(R.id.domain_settings_scrollview) != null) {  // The device is in single-paned mode and the domain settings fragment is displayed.
                     // Save the current domain settings.
                     saveDomainSettings(coordinatorLayout)
@@ -430,7 +427,7 @@ class DomainsActivity : AppCompatActivity(), AddDomainListener, DismissSnackbarI
                         undoDeleteSnackbar!!.dismiss()
                     } else {
                         // Go home.
-                        NavUtils.navigateUpFromSameTask(this)
+                        finish()
                     }
                 }
             }
index 2b9ad6376d95ea13ab2b23eed18fba1de73534c3..db9538141593b79d894428c64bc3ba062c3dd8ea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2015-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2015-2022 Soren Stoutner <soren@stoutner.com>.
  *
  * Download cookie code contributed 2017 Hendrik Knackstedt.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
  *
@@ -278,6 +278,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
     // Declare the class variables
     private boolean bottomAppBar;
+    private boolean displayAdditionalAppBarIcons;
     private boolean displayingFullScreenVideo;
     private boolean downloadWithExternalApp;
     private boolean fullScreenBrowsingModeEnabled;
@@ -498,9 +499,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
 
         // Get the preferences.
-        String appTheme = sharedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
+        String appTheme = sharedPreferences.getString(getString(R.string.app_theme_key), getString(R.string.app_theme_default_value));
         boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
         bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false);
+        displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
 
         // Get the theme entry values string array.
         String[] appThemeEntryValuesStringArray = getResources().getStringArray(R.array.app_theme_entry_values);
@@ -666,7 +668,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 }
 
                 // Add a new tab if specified in the preferences.
-                if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {  // Load the URL in a new tab.
+                if (sharedPreferences.getBoolean(getString(R.string.open_intents_in_new_tab_key), true)) {  // Load the URL in a new tab.
                     // Set the loading new intent flag.
                     loadingNewIntent = true;
 
@@ -973,12 +975,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Disable the clear form data menu item if the API >= 26 so that the status of the main Clear Data is calculated correctly.
         optionsClearFormDataMenuItem.setEnabled(Build.VERSION.SDK_INT < 26);
 
-        // Get the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get the dark theme and app bar preferences.
-        boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
-
         // Set the status of the additional app bar icons.  Setting the refresh menu item to `SHOW_AS_ACTION_ALWAYS` makes it appear even on small devices like phones.
         if (displayAdditionalAppBarIcons) {
             optionsRefreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
@@ -3523,13 +3519,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
 
         // Store the values from the shared preferences in variables.
-        incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false);
+        incognitoModeEnabled = sharedPreferences.getBoolean(getString(R.string.incognito_mode_key), false);
         sanitizeTrackingQueries = sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true);
         sanitizeAmpRedirects = sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true);
-        proxyMode = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
-        fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false);
+        proxyMode = sharedPreferences.getString(getString(R.string.proxy_key), getString(R.string.proxy_default_value));
+        fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean(getString(R.string.full_screen_browsing_mode_key), false);
+        hideAppBar = sharedPreferences.getBoolean(getString(R.string.hide_app_bar_key), true);
         downloadWithExternalApp = sharedPreferences.getBoolean(getString(R.string.download_with_external_app_key), false);
-        hideAppBar = sharedPreferences.getBoolean("hide_app_bar", true);
         scrollAppBar = sharedPreferences.getBoolean(getString(R.string.scroll_app_bar_key), true);
 
         // Apply the saved proxy mode if the app has been restarted.
@@ -3542,14 +3538,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         }
 
         // Get the search string.
-        String searchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
+        String searchString = sharedPreferences.getString(getString(R.string.search_key), getString(R.string.search_default_value));
 
         // Set the search string.
-        if (searchString.equals("Custom URL")) {  // A custom search string is used.
-            searchURL = sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value));
-        } else {  // A custom search string is not used.
+        if (searchString.equals(getString(R.string.custom_url_item)))
+            searchURL = sharedPreferences.getString(getString(R.string.search_custom_url_key), getString(R.string.search_custom_url_default_value));
+        else
             searchURL = searchString;
-        }
 
         // Apply the proxy.
         applyProxy(false);
@@ -4101,17 +4096,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.domain_settings_url_background, null));
             } else {  // The new URL does not have custom domain settings.  Load the defaults.
                 // Store the values from the shared preferences.
-                nestedScrollWebView.getSettings().setJavaScriptEnabled(sharedPreferences.getBoolean("javascript", false));
+                nestedScrollWebView.getSettings().setJavaScriptEnabled(sharedPreferences.getBoolean(getString(R.string.javascript_key), false));
                 nestedScrollWebView.setAcceptCookies(sharedPreferences.getBoolean(getString(R.string.cookies_key), false));
-                nestedScrollWebView.getSettings().setDomStorageEnabled(sharedPreferences.getBoolean("dom_storage", false));
-                boolean saveFormData = sharedPreferences.getBoolean("save_form_data", false);  // Form data can be removed once the minimum API >= 26.
-                nestedScrollWebView.setEasyListEnabled(sharedPreferences.getBoolean("easylist", true));
-                nestedScrollWebView.setEasyPrivacyEnabled(sharedPreferences.getBoolean("easyprivacy", true));
-                nestedScrollWebView.setFanboysAnnoyanceListEnabled(sharedPreferences.getBoolean("fanboys_annoyance_list", true));
-                nestedScrollWebView.setFanboysSocialBlockingListEnabled(sharedPreferences.getBoolean("fanboys_social_blocking_list", true));
-                nestedScrollWebView.setUltraListEnabled(sharedPreferences.getBoolean("ultralist", true));
-                nestedScrollWebView.setUltraPrivacyEnabled(sharedPreferences.getBoolean("ultraprivacy", true));
-                nestedScrollWebView.setBlockAllThirdPartyRequests(sharedPreferences.getBoolean("block_all_third_party_requests", false));
+                nestedScrollWebView.getSettings().setDomStorageEnabled(sharedPreferences.getBoolean(getString(R.string.dom_storage_key), false));
+                boolean saveFormData = sharedPreferences.getBoolean(getString(R.string.save_form_data_key), false);  // Form data can be removed once the minimum API >= 26.
+                nestedScrollWebView.setEasyListEnabled(sharedPreferences.getBoolean(getString(R.string.easylist_key), true));
+                nestedScrollWebView.setEasyPrivacyEnabled(sharedPreferences.getBoolean(getString(R.string.easyprivacy_key), true));
+                nestedScrollWebView.setFanboysAnnoyanceListEnabled(sharedPreferences.getBoolean(getString(R.string.fanboys_annoyance_list_key), true));
+                nestedScrollWebView.setFanboysSocialBlockingListEnabled(sharedPreferences.getBoolean(getString(R.string.fanboys_social_blocking_list_key), true));
+                nestedScrollWebView.setUltraListEnabled(sharedPreferences.getBoolean(getString(R.string.ultralist_key), true));
+                nestedScrollWebView.setUltraPrivacyEnabled(sharedPreferences.getBoolean(getString(R.string.ultraprivacy_key), true));
+                nestedScrollWebView.setBlockAllThirdPartyRequests(sharedPreferences.getBoolean(getString(R.string.block_all_third_party_requests_key), false));
 
                 // Apply the default cookie setting.
                 cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptCookies());
@@ -4685,7 +4680,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 }
 
                 // Add a new tab if specified in the preferences.
-                if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {  // Load the URL in a new tab.
+                if (sharedPreferences.getBoolean(getString(R.string.open_intents_in_new_tab_key), true)) {  // Load the URL in a new tab.
                     // Set the loading new intent flag.
                     loadingNewIntent = true;
 
@@ -4813,7 +4808,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         bookmarksDatabaseHelper.close();
 
         // Get the status of the clear everything preference.
-        boolean clearEverything = sharedPreferences.getBoolean("clear_everything", true);
+        boolean clearEverything = sharedPreferences.getBoolean(getString(R.string.clear_everything_key), true);
 
         // Get a handle for the runtime.
         Runtime runtime = Runtime.getRuntime();
@@ -4823,7 +4818,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         String privateDataDirectoryString = getApplicationInfo().dataDir;
 
         // Clear cookies.
-        if (clearEverything || sharedPreferences.getBoolean("clear_cookies", true)) {
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_cookies_key), true)) {
             // Request the cookies be deleted.
             CookieManager.getInstance().removeAllCookies(null);
 
@@ -4842,7 +4837,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         }
 
         // Clear DOM storage.
-        if (clearEverything || sharedPreferences.getBoolean("clear_dom_storage", true)) {
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_dom_storage_key), true)) {
             // Ask `WebStorage` to clear the DOM storage.
             WebStorage webStorage = WebStorage.getInstance();
             webStorage.deleteAllData();
@@ -4870,7 +4865,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         }
 
         // Clear form data if the API < 26.
-        if ((Build.VERSION.SDK_INT < 26) && (clearEverything || sharedPreferences.getBoolean("clear_form_data", true))) {
+        if ((Build.VERSION.SDK_INT < 26) && (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_form_data_key), true))) {
             WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(this);
             webViewDatabase.clearFormData();
 
@@ -4902,7 +4897,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         }
 
         // Clear the cache.
-        if (clearEverything || sharedPreferences.getBoolean("clear_cache", true)) {
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_cache_key), true)) {
             // Clear the cache from each WebView.
             for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
                 // Get the WebView tab fragment.
@@ -6100,13 +6095,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     // Set the title.
                     optionsRefreshMenuItem.setTitle(R.string.stop);
 
-                    // Get the app bar and theme preferences.
-                    boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
-
-                    // Set the icon if it is displayed in the AppBar.  Once the minimum API is >= 26, the blue and black icons can be combined with a tint list.
-                    if (displayAdditionalAppBarIcons) {
+                    // Set the icon if it is displayed in the AppBar.
+                    if (displayAdditionalAppBarIcons)
                         optionsRefreshMenuItem.setIcon(R.drawable.close_blue);
-                    }
                 }
             }
 
@@ -6122,14 +6113,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     // Reset the Refresh title.
                     optionsRefreshMenuItem.setTitle(R.string.refresh);
 
-                    // Get the app bar and theme preferences.
-                    boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), false);
-
-                    // If the icon is displayed in the app bar, reset it according to the theme.
-                    if (displayAdditionalAppBarIcons) {
-                        // Set the icon.
+                    // Reset the icon if it is displayed in the app bar.
+                    if (displayAdditionalAppBarIcons)
                         optionsRefreshMenuItem.setIcon(R.drawable.refresh_enabled);
-                    }
                 }
 
                  // Get the application's private data directory, which will be something like `/data/user/0/com.stoutner.privacybrowser.standard`,
@@ -6378,4 +6364,4 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java
deleted file mode 100644 (file)
index 66986ba..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright © 2016-2020,2022 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
- *
- * 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 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 Android.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.stoutner.privacybrowser.activities;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.WindowManager;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.stoutner.privacybrowser.fragments.SettingsFragment;
-
-public class SettingsActivity extends AppCompatActivity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-
-        // Get the screenshot and theme preferences.
-        boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
-
-        // Disable screenshots if not allowed.
-        if (!allowScreenshots) {
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
-        }
-
-        // Run the default commands.
-        super.onCreate(savedInstanceState);
-
-        // Display the settings fragment.
-        getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.kt b/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.kt
new file mode 100644 (file)
index 0000000..35cb1f6
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2016-2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ *
+ * 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 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 Android.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.activities
+
+import android.os.Bundle
+import android.view.MenuItem
+import android.view.WindowManager
+
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import androidx.preference.PreferenceManager
+
+import com.stoutner.privacybrowser.R
+import com.stoutner.privacybrowser.fragments.SettingsFragment
+
+class SettingsActivity : AppCompatActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        // Get a handle for the shared preferences.
+        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
+
+        // Get the preference.
+        val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
+        val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
+
+        // Disable screenshots if not allowed.
+        if (!allowScreenshots) window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+
+        // Run the default commands.
+        super.onCreate(savedInstanceState)
+
+        // Set the content view.
+        if (bottomAppBar) {
+            setContentView(R.layout.settings_bottom_appbar)
+        } else {
+            setContentView(R.layout.settings_top_appbar)
+        }
+
+        // Get a handle for the toolbar.
+        val toolbar = findViewById<Toolbar>(R.id.toolbar)
+
+        // Set the support action bar.
+        setSupportActionBar(toolbar)
+
+        // Get a handle for the action bar.
+        val actionBar = supportActionBar!!
+
+        // Display the home arrow on the action bar.
+        actionBar.setDisplayHomeAsUpEnabled(true)
+
+        // Display the settings fragment.
+        supportFragmentManager.beginTransaction().replace(R.id.preferences_framelayout, SettingsFragment()).commit()
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean {
+        // As the back arrow is the only option, finish the activity.
+        finish()
+
+        // Consume the event.
+        return true
+    }
+}
index 0b2d6ed0a6a6ef554a6e2c806cbda06693adf658..f1cc8cb339b3ff90938136d78665c4ca0f3a88ad 100644 (file)
@@ -113,7 +113,7 @@ class AddDomainDialog : DialogFragment() {
         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
 
         // Get the screenshot preference.
-        val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots), false)
+        val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
 
         // Disable screenshots if not allowed.
         if (!allowScreenshots) {
index 342c35855c61bd1f7729db58cabf8839aa7da419..6d74af793ef4aa86bb51f5ab95d19231d3fac350 100644 (file)
@@ -286,8 +286,8 @@ class AboutVersionFragment : Fragment() {
         systemTotalMemoryLabel = getString(R.string.system_total_memory) + "  "
         val easyListLabel = getString(R.string.easylist_label) + "  "
         val easyPrivacyLabel = getString(R.string.easyprivacy_label) + "  "
-        val fanboyAnnoyanceLabel = getString(R.string.fanboy_annoyance_label) + "  "
-        val fanboySocialLabel = getString(R.string.fanboy_social_label) + "  "
+        val fanboyAnnoyanceLabel = getString(R.string.fanboys_annoyance_label) + "  "
+        val fanboySocialLabel = getString(R.string.fanboys_social_label) + "  "
         val ultraListLabel = getString(R.string.ultralist_label) + "  "
         val ultraPrivacyLabel = getString(R.string.ultraprivacy_label) + "  "
         val issuerDNLabel = getString(R.string.issuer_dn) + "  "
diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
deleted file mode 100644 (file)
index d7aecd3..0000000
+++ /dev/null
@@ -1,1443 +0,0 @@
-/*
- * Copyright © 2016-2022 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
- *
- * 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 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 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.os.Handler;
-import android.os.Looper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.webkit.WebView;
-import android.widget.ArrayAdapter;
-
-import androidx.appcompat.app.AppCompatDelegate;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceFragmentCompat;
-
-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 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 xRequestedWithHeaderPreference;
-    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 trackingQueriesPreference;
-    private Preference ampRedirectsPreference;
-    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 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 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(getString(R.string.user_agent_key));
-        customUserAgentPreference = findPreference("custom_user_agent");
-        xRequestedWithHeaderPreference = findPreference(getString(R.string.x_requested_with_header_key));
-        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");
-        trackingQueriesPreference = findPreference(getString(R.string.tracking_queries_key));
-        ampRedirectsPreference = findPreference(getString(R.string.amp_redirects_key));
-        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(getString(R.string.font_size_key));
-        openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
-        swipeToRefreshPreference = findPreference(getString(R.string.swipe_to_refresh_key));
-        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(getString(R.string.webview_theme_key));
-        wideViewportPreference = findPreference(getString(R.string.wide_viewport_key));
-        displayWebpageImagesPreference = findPreference(getString(R.string.display_webpage_images_key));
-
-        // 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 xRequestedWithHeaderPreference != 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 trackingQueriesPreference != null;
-        assert ampRedirectsPreference != 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 userAgentName = sharedPreferences.getString(getString(R.string.user_agent_key), 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);
-        }
-
-        // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
-        fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
-
-
-        // 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 the `bare_webview` will not be displayed.
-        @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
-
-        // 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(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + defaultUserAgent);
-                break;
-
-            case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
-                // Set the summary text.
-                userAgentPreference.setSummary(R.string.custom_user_agent);
-                break;
-
-            default:
-                // Get the user agent summary from the user agent data array.
-                userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
-        }
-
-        // Set the summary text for the custom user agent preference.
-        customUserAgentPreference.setSummary(sharedPreferences.getString(getString(R.string.custom_user_agent_key), 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 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.
-            searchPreference.setSummary(R.string.custom_url);
-        } else {
-            // Set the array value as the summary text.
-            searchPreference.setSummary(searchString);
-        }
-
-        // 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)));
-
-        // Only enable the search custom URL preference if the search is set to `Custom URL`.
-        searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
-
-
-        // 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 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));
-
-
-        // 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.
-        homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
-
-
-        // Set the font size as the summary text for the preference.
-        fontSizePreference.setSummary(sharedPreferences.getString(getString(R.string.font_size_key), 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));
-
-        // Declare 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]);
-
-        // Disable the WebView theme preference if the API >= 33 and the app theme is set to light.
-        webViewThemePreference.setEnabled((Build.VERSION.SDK_INT < 33) || (appThemeEntryNumber != 1));
-
-
-        // 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(getString(R.string.webview_theme_key), 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 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 {
-            javaScriptPreference.setIcon(R.drawable.privacy_mode);
-        }
-
-        // Set the cookies icon.
-        if (sharedPreferences.getBoolean(getString(R.string.cookies_key), false)) {
-            cookiesPreference.setIcon(R.drawable.cookies_enabled);
-        } else {
-            cookiesPreference.setIcon(R.drawable.cookies_disabled);
-        }
-
-        // 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 {  // DOM storage is disabled.
-                domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
-            }
-        } else {  // The preference is disabled.  The icon should be ghosted.
-            domStoragePreference.setIcon(R.drawable.dom_storage_ghosted);
-        }
-
-        // 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 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 X-Requested With header icon.
-        if (sharedPreferences.getBoolean(getString(R.string.x_requested_with_header_key), true))
-            xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_enabled);
-        else
-            xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_disabled);
-
-        // Set the incognito mode icon.
-        if (sharedPreferences.getBoolean("incognito_mode", false))
-            incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
-        else
-            incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
-
-        // Set the allow screenshots icon.
-        if (sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false))
-            allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled);
-        else
-            allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled);
-
-        // Set the EasyList icon.
-        if (sharedPreferences.getBoolean("easylist", true))
-            easyListPreference.setIcon(R.drawable.block_ads_enabled);
-        else
-            easyListPreference.setIcon(R.drawable.block_ads_disabled);
-
-        // Set the EasyPrivacy icon.
-        if (sharedPreferences.getBoolean("easyprivacy", true))
-            easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled);
-        else
-            easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled);
-
-        // 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 Fanboy social blocking list icon.
-            if (fanboySocialBlockingEnabled) {
-                fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled);
-            } else {
-                fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled);
-            }
-        }
-
-        // Set the UltraList icon.
-        if (sharedPreferences.getBoolean("ultralist", true)){
-            ultraListPreference.setIcon(R.drawable.block_ads_enabled);
-        } else {
-            ultraListPreference.setIcon(R.drawable.block_ads_disabled);
-        }
-
-        // Set the UltraPrivacy icon.
-        if (sharedPreferences.getBoolean("ultraprivacy", true)) {
-            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled);
-        } else {
-            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled);
-        }
-
-        // 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 the Tracking Queries icon.
-        if (sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true)) {
-            trackingQueriesPreference.setIcon(R.drawable.modify_url_enabled);
-        } else {
-            trackingQueriesPreference.setIcon(R.drawable.modify_url_disabled);
-        }
-
-        // Set the AMP Redirects icon.
-        if (sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true)) {
-            ampRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
-        } else {
-            ampRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
-        }
-
-        // Set the search custom URL icon.
-        if (searchCustomURLPreference.isEnabled()) {
-            searchCustomURLPreference.setIcon(R.drawable.search_custom_enabled);
-        } else {
-            searchCustomURLPreference.setIcon(R.drawable.search_custom_ghosted);
-        }
-
-        // 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);
-
-            // 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 {
-                proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted);
-            }
-        }
-
-        // 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 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);
-        }
-
-        // 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);
-        }
-
-        // 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);
-        }
-
-        // 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);
-            }
-        }
-
-        // 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);
-        }
-
-        // 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);
-        }
-
-        // 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);
-        }
-
-        // Set the swipe to refresh preference icon.
-        if (sharedPreferences.getBoolean(getString(R.string.swipe_to_refresh_key), true))
-            swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
-        else
-            swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
-
-        // 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);
-
-        // 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);
-
-        // 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);
-
-        // 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);
-
-        // Set the WebView theme preference icon.
-        if (webViewThemePreference.isEnabled()) {  // The WebView theme preference is enabled.
-            switch (webViewThemeEntryNumber) {
-                case 0:  // The system default WebView theme is selected.
-                    // Get the current theme status.
-                    int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                    // 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 1:  // The light WebView theme is selected.
-                    // Set the icon.
-                    webViewThemePreference.setIcon(R.drawable.webview_light_theme);
-                    break;
-
-                case 2:  // The dark WebView theme is selected.
-                    // Set the icon.
-                    webViewThemePreference.setIcon(R.drawable.webview_dark_theme);
-                    break;
-            }
-        } else {  // The WebView theme preference is disabled.
-            webViewThemePreference.setIcon(R.drawable.webview_theme_ghosted);
-        }
-
-        // Set the wide viewport preference icon.
-        if (sharedPreferences.getBoolean(getString(R.string.wide_viewport_key), true)) {
-            wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled);
-        } else {
-            wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled);
-        }
-
-        // Set the display webpage images preference icon.
-        if (sharedPreferences.getBoolean(getString(R.string.display_webpage_images_key), true)) {
-            displayWebpageImagesPreference.setIcon(R.drawable.images_enabled);
-        } else {
-            displayWebpageImagesPreference.setIcon(R.drawable.images_disabled);
-        }
-    }
-
-    // The listener should be unregistered when the app is paused.
-    @Override
-    public void onPause() {
-        // Run the default commands.
-        super.onPause();
-
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
-
-        // Remove the incorrect lint warning below that the shared preferences might be null.
-        assert sharedPreferences != null;
-
-        // Unregister the shared preference listener.
-        sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
-    }
-
-    // The listener should be re-registered when the app is resumed.
-    @Override
-    public void onResume() {
-        // Run the default commands.
-        super.onResume();
-
-        // Get a new shared preference change listener.
-        sharedPreferenceChangeListener = getSharedPreferenceChangeListener(requireContext());
-
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
-
-        // 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);
-                        }
-                    } 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(context.getString(R.string.user_agent_key), 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(context.getString(R.string.custom_user_agent_key), context.getString(R.string.custom_user_agent_default_value)));
-                    break;
-
-                case "x_requested_with_header":
-                    // Update the icon.
-                    if (sharedPreferences.getBoolean(context.getString(R.string.x_requested_with_header_key), true))
-                        xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_enabled);
-                    else
-                        xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_disabled);
-
-                    // Restart Privacy Browser.
-                    restartPrivacyBrowser();
-                    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);
-                        }
-                    }
-
-                    // 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 "tracking_queries":
-                    // Update the icon.
-                    if (sharedPreferences.getBoolean(context.getString(R.string.tracking_queries_key), true)) {
-                        trackingQueriesPreference.setIcon(R.drawable.modify_url_enabled);
-                    } else {
-                        trackingQueriesPreference.setIcon(R.drawable.modify_url_disabled);
-                    }
-                    break;
-
-                case "amp_redirects":
-                    // Update the icon.
-                    if (sharedPreferences.getBoolean(context.getString(R.string.amp_redirects_key), true)) {
-                        ampRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
-                    } else {
-                        ampRedirectsPreference.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 {
-                            proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted);
-                        }
-                    }
-                    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 {
-                            hideAppBarPreference.setIcon(R.drawable.app_bar_disabled);
-                        }
-                    } 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 {
-                            clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled);
-                        }
-                    }
-
-                    // 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(context.getString(R.string.font_size_key), 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(context.getString(R.string.swipe_to_refresh_key), 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));
-
-                    // Declare 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 (newAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
-                        // Store the app theme entry number.
-                        appThemeEntryNumber = 1;
-                    } else if (newAppTheme.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;
-                    }
-
-                    // 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.
-                    switch (appThemeEntryNumber) {
-                        case 0:  // 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);
-                            }
-                            break;
-
-                        case 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);
-                            break;
-
-                        case 2:
-                            // Update the theme preference summary text.
-                            appThemePreference.setSummary(appThemeEntriesStringArray[2]);
-
-                            // Apply the new theme.
-                            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
-                            break;
-                    }
-
-                    // Disable the WebView theme preference if the API >= 33 and the app theme is set to light.
-                    webViewThemePreference.setEnabled((Build.VERSION.SDK_INT < 33) || (appThemeEntryNumber != 1));
-
-                    // Get the WebView theme.
-                    String webViewTheme = sharedPreferences.getString(context.getString(R.string.webview_theme_key), context.getString(R.string.webview_theme_default_value));
-
-                    // Declare a WebView theme entry number.
-                    int webViewThemeEntryNumber;
-
-                    // 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 (webViewTheme.equals(webViewThemeEntriesStringArray[1])) {  // The light theme is selected.
-                        // Store the WebView theme entry number.
-                        webViewThemeEntryNumber = 1;
-                    } else if (webViewTheme.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;
-                    }
-
-                    // Update the WebView theme preference icon.
-                    if (webViewThemePreference.isEnabled()) {  // The WebView theme preference is enabled.
-                        switch (webViewThemeEntryNumber) {
-                            case 0:  // The system default WebView theme is selected.
-                                // Get the current theme status.
-                                int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                                // 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 1:  // The light WebView theme is selected.
-                                // Set the icon.
-                                webViewThemePreference.setIcon(R.drawable.webview_light_theme);
-                                break;
-
-                            case 2:  // The dark WebView theme is selected.
-                                // Set the icon.
-                                webViewThemePreference.setIcon(R.drawable.webview_dark_theme);
-                                break;
-                        }
-                    } else {  // The WebView theme preference is disabled.
-                        webViewThemePreference.setIcon(R.drawable.webview_theme_ghosted);
-                    }
-                    break;
-
-                case "webview_theme":
-                    // Get the new WebView theme.
-                    String newWebViewTheme = sharedPreferences.getString(context.getString(R.string.webview_theme_key), context.getString(R.string.webview_theme_default_value));
-
-                    // Declare 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 new WebView theme entry number.
-                        newWebViewThemeEntryNumber = 2;
-                    } else {  // The system default theme is selected.
-                        // Store the new WebView theme entry number.
-                        newWebViewThemeEntryNumber = 0;
-                    }
-
-                    // Update the icon.
-                    switch (newWebViewThemeEntryNumber) {
-                        case 0:  // The system default WebView theme is selected.
-                            // Get the current theme status.
-                            int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-                            // 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(context.getString(R.string.wide_viewport_key), 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(context.getString(R.string.display_webpage_images_key), true)) {
-                        displayWebpageImagesPreference.setIcon(R.drawable.images_enabled);
-                    } else {
-                        displayWebpageImagesPreference.setIcon(R.drawable.images_disabled);
-                    }
-                    break;
-            }
-        };
-    }
-
-    private void restartPrivacyBrowser() {
-        // Create an intent to restart Privacy Browser.
-        Intent restartIntent = requireActivity().getParentActivityIntent();
-
-        // 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);
-    }
-}
diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.kt b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.kt
new file mode 100644 (file)
index 0000000..c6fb15f
--- /dev/null
@@ -0,0 +1,1234 @@
+/*
+ * Copyright 2016-2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ *
+ * 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 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 Android.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.fragments
+
+import android.annotation.SuppressLint
+import android.content.Intent
+import android.content.SharedPreferences
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener
+import android.content.res.Configuration
+import android.os.Build
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.webkit.WebView
+import android.widget.ArrayAdapter
+
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceFragmentCompat
+
+import com.stoutner.privacybrowser.R
+import com.stoutner.privacybrowser.activities.MainWebViewActivity
+import com.stoutner.privacybrowser.helpers.ProxyHelper
+import kotlin.system.exitProcess
+
+class SettingsFragment : PreferenceFragmentCompat() {
+    // Declare the class variables.
+    private lateinit var appThemeEntriesStringArray: Array<String>
+    private lateinit var appThemeEntryValuesStringArray: Array<String>
+    private lateinit var defaultUserAgent: String
+    private lateinit var sharedPreferenceChangeListener: OnSharedPreferenceChangeListener
+    private lateinit var translatedUserAgentNamesArray: Array<String>
+    private lateinit var userAgentDataArray: Array<String>
+    private lateinit var userAgentNamesArray: ArrayAdapter<CharSequence>
+    private lateinit var webViewThemeEntriesStringArray: Array<String>
+    private lateinit var webViewThemeEntryValuesStringArray: Array<String>
+
+    // Define the the class views.
+    private lateinit var javaScriptPreference: Preference
+    private lateinit var cookiesPreference: Preference
+    private lateinit var domStoragePreference: Preference
+    private lateinit var formDataPreference: Preference  // The form data preference can be removed once the minimum API >= 26.
+    private lateinit var userAgentPreference: Preference
+    private lateinit var customUserAgentPreference: Preference
+    private lateinit var xRequestedWithHeaderPreference: Preference
+    private lateinit var incognitoModePreference: Preference
+    private lateinit var allowScreenshotsPreference: Preference
+    private lateinit var easyListPreference: Preference
+    private lateinit var easyPrivacyPreference: Preference
+    private lateinit var fanboyAnnoyanceListPreference: Preference
+    private lateinit var fanboySocialBlockingListPreference: Preference
+    private lateinit var ultraListPreference: Preference
+    private lateinit var ultraPrivacyPreference: Preference
+    private lateinit var blockAllThirdPartyRequestsPreference: Preference
+    private lateinit var trackingQueriesPreference: Preference
+    private lateinit var ampRedirectsPreference: Preference
+    private lateinit var searchPreference: Preference
+    private lateinit var searchCustomURLPreference: Preference
+    private lateinit var proxyPreference: Preference
+    private lateinit var proxyCustomUrlPreference: Preference
+    private lateinit var fullScreenBrowsingModePreference: Preference
+    private lateinit var hideAppBarPreference: Preference
+    private lateinit var clearEverythingPreference: Preference
+    private lateinit var clearCookiesPreference: Preference
+    private lateinit var clearDomStoragePreference: Preference
+    private lateinit var clearFormDataPreference: Preference  // The clear form data preference can be removed once the minimum API >= 26.
+    private lateinit var clearLogcatPreference: Preference
+    private lateinit var clearCachePreference: Preference
+    private lateinit var homepagePreference: Preference
+    private lateinit var fontSizePreference: Preference
+    private lateinit var openIntentsInNewTabPreference: Preference
+    private lateinit var swipeToRefreshPreference: Preference
+    private lateinit var downloadWithExternalAppPreference: Preference
+    private lateinit var scrollAppBarPreference: Preference
+    private lateinit var bottomAppBarPreference: Preference
+    private lateinit var displayAdditionalAppBarIconsPreference: Preference
+    private lateinit var appThemePreference: Preference
+    private lateinit var webViewThemePreference: Preference
+    private lateinit var wideViewportPreference: Preference
+    private lateinit var displayWebpageImagesPreference: Preference
+
+    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+        // Load the preferences from the XML file.
+        setPreferencesFromResource(R.xml.preferences, rootKey)
+
+        // Get a handle for the shared preferences.
+        val sharedPreferences = preferenceScreen.sharedPreferences!!
+
+        // Get handles for the preferences.
+        javaScriptPreference = findPreference(getString(R.string.javascript_key))!!
+        cookiesPreference = findPreference(getString(R.string.cookies_key))!!
+        domStoragePreference = findPreference(getString(R.string.dom_storage_key))!!
+        formDataPreference = findPreference(getString(R.string.save_form_data_key))!!  // The form data preference can be removed once the minimum API >= 26.
+        userAgentPreference = findPreference(getString(R.string.user_agent_key))!!
+        customUserAgentPreference = findPreference(getString(R.string.custom_user_agent_key))!!
+        xRequestedWithHeaderPreference = findPreference(getString(R.string.x_requested_with_header_key))!!
+        incognitoModePreference = findPreference(getString(R.string.incognito_mode_key))!!
+        allowScreenshotsPreference = findPreference(getString(R.string.allow_screenshots_key))!!
+        easyListPreference = findPreference(getString(R.string.easylist_key))!!
+        easyPrivacyPreference = findPreference(getString(R.string.easyprivacy_key))!!
+        fanboyAnnoyanceListPreference = findPreference(getString(R.string.fanboys_annoyance_list_key))!!
+        fanboySocialBlockingListPreference = findPreference(getString(R.string.fanboys_social_blocking_list_key))!!
+        ultraListPreference = findPreference(getString(R.string.ultralist_key))!!
+        ultraPrivacyPreference = findPreference(getString(R.string.ultraprivacy_key))!!
+        blockAllThirdPartyRequestsPreference = findPreference(getString(R.string.block_all_third_party_requests_key))!!
+        trackingQueriesPreference = findPreference(getString(R.string.tracking_queries_key))!!
+        ampRedirectsPreference = findPreference(getString(R.string.amp_redirects_key))!!
+        searchPreference = findPreference(getString(R.string.search_key))!!
+        searchCustomURLPreference = findPreference(getString(R.string.search_custom_url_key))!!
+        proxyPreference = findPreference(getString(R.string.proxy_key))!!
+        proxyCustomUrlPreference = findPreference(getString(R.string.proxy_custom_url_key))!!
+        fullScreenBrowsingModePreference = findPreference(getString(R.string.full_screen_browsing_mode_key))!!
+        hideAppBarPreference = findPreference(getString(R.string.hide_app_bar_key))!!
+        clearEverythingPreference = findPreference(getString(R.string.clear_everything_key))!!
+        clearCookiesPreference = findPreference(getString(R.string.clear_cookies_key))!!
+        clearDomStoragePreference = findPreference(getString(R.string.clear_dom_storage_key))!!
+        clearFormDataPreference = findPreference(getString(R.string.clear_form_data_key))!!  // The clear form data preference can be removed once the minimum API >= 26.
+        clearLogcatPreference = findPreference(getString(R.string.clear_logcat_key))!!
+        clearCachePreference = findPreference(getString(R.string.clear_cache_key))!!
+        homepagePreference = findPreference(getString(R.string.homepage_key))!!
+        fontSizePreference = findPreference(getString(R.string.font_size_key))!!
+        openIntentsInNewTabPreference = findPreference(getString(R.string.open_intents_in_new_tab_key))!!
+        swipeToRefreshPreference = findPreference(getString(R.string.swipe_to_refresh_key))!!
+        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(getString(R.string.app_theme_key))!!
+        webViewThemePreference = findPreference(getString(R.string.webview_theme_key))!!
+        wideViewportPreference = findPreference(getString(R.string.wide_viewport_key))!!
+        displayWebpageImagesPreference = findPreference(getString(R.string.display_webpage_images_key))!!
+
+        // Set the preference dependencies.
+        domStoragePreference.dependency = getString(R.string.javascript_key)
+        hideAppBarPreference.dependency = getString(R.string.full_screen_browsing_mode_key)
+
+        // Get strings from the preferences.
+        val userAgentName = sharedPreferences.getString(getString(R.string.user_agent_key), getString(R.string.user_agent_default_value))
+        val searchString = sharedPreferences.getString(getString(R.string.search_key), getString(R.string.search_default_value))
+        val proxyString = sharedPreferences.getString(getString(R.string.proxy_key), getString(R.string.proxy_default_value))
+
+        // Get booleans that are used in multiple places from the preferences.
+        val javaScriptEnabled = sharedPreferences.getBoolean(getString(R.string.javascript_key), false)
+        val fanboyAnnoyanceListEnabled = sharedPreferences.getBoolean(getString(R.string.fanboys_annoyance_list_key), true)
+        val fanboySocialBlockingEnabled = sharedPreferences.getBoolean(getString(R.string.fanboys_social_blocking_list_key), true)
+        val fullScreenBrowsingMode = sharedPreferences.getBoolean(getString(R.string.full_screen_browsing_mode_key), false)
+        val clearEverything = sharedPreferences.getBoolean(getString(R.string.clear_everything_key), 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.
+            val privacyCategory = findPreference<PreferenceCategory>(getString(R.string.privacy_category_key))!!
+            val clearAndExitCategory = findPreference<PreferenceCategory>(getString(R.string.clear_and_exit_category_key))!!
+
+            // Remove the form data preferences.
+            privacyCategory.removePreference(formDataPreference)
+            clearAndExitCategory.removePreference(clearFormDataPreference)
+        }
+
+        // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
+        fanboySocialBlockingListPreference.isEnabled = !fanboyAnnoyanceListEnabled
+
+
+        // Inflate a WebView to get the default user agent.
+        val inflater = requireActivity().layoutInflater
+
+        // `@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") val bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false)
+
+        // Get a handle for the bare WebView.
+        val bareWebView = bareWebViewLayout.findViewById<WebView>(R.id.bare_webview)
+
+        // Get the default user agent.
+        defaultUserAgent = bareWebView.settings.userAgentString
+
+        // 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)
+
+        // Populate the user agent summary.
+        when (val userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName)) {
+            // 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.
+            MainWebViewActivity.UNRECOGNIZED_USER_AGENT -> userAgentPreference.summary = userAgentName
+
+            // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
+            MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT -> userAgentPreference.summary = "${translatedUserAgentNamesArray[userAgentArrayPosition]}:\n$defaultUserAgent"
+
+            // Display the custom user agent.
+            MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT -> userAgentPreference.setSummary(R.string.custom_user_agent)
+
+            // Get the user agent summary from the user agent data array.
+            else -> userAgentPreference.summary = "${translatedUserAgentNamesArray[userAgentArrayPosition]}:\n${userAgentDataArray[userAgentArrayPosition]}"
+        }
+
+        // Set the summary text for the custom user agent preference.
+        customUserAgentPreference.summary = sharedPreferences.getString(getString(R.string.custom_user_agent_key), getString(R.string.custom_user_agent_default_value))
+
+        // Only enable the custom user agent preference if the user agent is set to custom.
+        customUserAgentPreference.isEnabled = (userAgentPreference.summary == getString(R.string.custom_user_agent))
+
+        // Set the search URL as the summary text for the search preference when the preference screen is loaded.
+        if (searchString == getString(R.string.custom_url_item)) {
+            // 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.summary = searchString
+        }
+
+        // Set the summary text for the search custom URL (the default is `""`).
+        searchCustomURLPreference.summary = sharedPreferences.getString(getString(R.string.search_custom_url_key), getString(R.string.search_custom_url_default_value))
+
+        // Only enable the search custom URL preference if the search is set to a custom URL.
+        searchCustomURLPreference.isEnabled = (searchString == getString(R.string.custom_url_item))
+
+        // Set the summary text for the proxy preference.
+        proxyPreference.summary = when (proxyString) {
+            ProxyHelper.NONE -> getString(R.string.no_proxy_enabled)
+            ProxyHelper.TOR -> getString(R.string.tor_enabled)
+            ProxyHelper.I2P -> getString(R.string.i2p_enabled)
+            ProxyHelper.CUSTOM -> getString(R.string.custom_proxy)
+            else -> getString(R.string.no_proxy_enabled)
+        }
+
+        // Set the summary text for the custom proxy URL.
+        proxyCustomUrlPreference.summary = 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.isEnabled = proxyString == ProxyHelper.CUSTOM
+
+        // Set the status of the clear and exit preferences.
+        clearCookiesPreference.isEnabled = !clearEverything
+        clearDomStoragePreference.isEnabled = !clearEverything
+        clearFormDataPreference.isEnabled = !clearEverything  // Clear form data can be removed once the minimum API is >= 26.
+        clearLogcatPreference.isEnabled = !clearEverything
+        clearCachePreference.isEnabled = !clearEverything
+
+        // Set the homepage URL as the summary text for the homepage preference.
+        homepagePreference.summary = sharedPreferences.getString(getString(R.string.homepage_key), getString(R.string.homepage_default_value))
+
+        // Set the font size as the summary text for the preference.
+        fontSizePreference.summary = sharedPreferences.getString(getString(R.string.font_size_key), 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 app theme entry number that matches the current app theme.
+        val appThemeEntryNumber: Int = when (sharedPreferences.getString(getString(R.string.app_theme_key), getString(R.string.app_theme_default_value))) {
+            appThemeEntryValuesStringArray[1] -> 1  // The light theme is selected.
+            appThemeEntryValuesStringArray[2] -> 2  // The dark theme is selected.
+            else -> 0  // The system default theme is selected.
+        }
+
+        // Set the current theme as the summary text for the preference.
+        appThemePreference.summary = appThemeEntriesStringArray[appThemeEntryNumber]
+
+        // Enable the WebView theme preference if the API < 33 or the app theme is not set to light.  Google no longer allows light themes to display dark WebViews.
+        webViewThemePreference.isEnabled = ((Build.VERSION.SDK_INT < 33) || (appThemeEntryNumber != 1))
+
+        // 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 WebView theme entry number that matches the current WebView theme.
+        val webViewThemeEntryNumber: Int = when (sharedPreferences.getString(getString(R.string.webview_theme_key), getString(R.string.webview_theme_default_value))) {
+            webViewThemeEntryValuesStringArray[1] -> 1  // The light theme is selected.
+            webViewThemeEntryValuesStringArray[2] -> 2  // The dark theme is selected.
+            else -> 0  // The system default theme is selected.
+        }
+
+        // Set the current theme as the summary text for the preference.
+        webViewThemePreference.summary = webViewThemeEntriesStringArray[webViewThemeEntryNumber]
+
+        // Set the JavaScript icon.
+        if (javaScriptEnabled)
+            javaScriptPreference.setIcon(R.drawable.javascript_enabled)
+        else
+            javaScriptPreference.setIcon(R.drawable.privacy_mode)
+
+        // Set the cookies icon.
+        if (sharedPreferences.getBoolean(getString(R.string.cookies_key), false))
+            cookiesPreference.setIcon(R.drawable.cookies_enabled)
+        else
+            cookiesPreference.setIcon(R.drawable.cookies_disabled)
+
+        // Set the DOM storage icon.
+        if (javaScriptEnabled) {  // JavaScript is enabled.
+            if (sharedPreferences.getBoolean(getString(R.string.dom_storage_key), false))  // DOM storage is enabled.
+                domStoragePreference.setIcon(R.drawable.dom_storage_enabled)
+            else  // DOM storage is disabled.
+                domStoragePreference.setIcon(R.drawable.dom_storage_disabled)
+        } else {  // JavaScript is disabled.  DOM storage should be ghosted.
+            domStoragePreference.setIcon(R.drawable.dom_storage_ghosted)
+        }
+
+        // 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(getString(R.string.save_form_data_key), false))
+                formDataPreference.setIcon(R.drawable.form_data_enabled)
+            else
+                formDataPreference.setIcon(R.drawable.form_data_disabled)
+        }
+
+        // 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 X-Requested With header icon.
+        if (sharedPreferences.getBoolean(getString(R.string.x_requested_with_header_key), true))
+            xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_enabled)
+        else
+            xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_disabled)
+
+        // Set the incognito mode icon.
+        if (sharedPreferences.getBoolean(getString(R.string.incognito_mode_key), false))
+            incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled)
+        else
+            incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled)
+
+        // Set the allow screenshots icon.
+        if (sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false))
+            allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled)
+        else
+            allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled)
+
+        // Set the EasyList icon.
+        if (sharedPreferences.getBoolean(getString(R.string.easylist_key), true))
+            easyListPreference.setIcon(R.drawable.block_ads_enabled)
+        else
+            easyListPreference.setIcon(R.drawable.block_ads_disabled)
+
+        // Set the EasyPrivacy icon.
+        if (sharedPreferences.getBoolean(getString(R.string.easyprivacy_key), true))
+            easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled)
+        else
+            easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled)
+
+        // 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 Fanboy social blocking list icon.
+            if (fanboySocialBlockingEnabled)
+                fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled)
+            else
+                fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled)
+        }
+
+        // Set the UltraList icon.
+        if (sharedPreferences.getBoolean(getString(R.string.ultralist_key), true))
+            ultraListPreference.setIcon(R.drawable.block_ads_enabled)
+        else
+            ultraListPreference.setIcon(R.drawable.block_ads_disabled)
+
+        // Set the UltraPrivacy icon.
+        if (sharedPreferences.getBoolean(getString(R.string.ultraprivacy_key), true))
+            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled)
+        else
+            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled)
+
+        // Set the block all third-party requests icon.
+        if (sharedPreferences.getBoolean(getString(R.string.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 the Tracking Queries icon.
+        if (sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true))
+            trackingQueriesPreference.setIcon(R.drawable.modify_url_enabled)
+        else
+            trackingQueriesPreference.setIcon(R.drawable.modify_url_disabled)
+
+        // Set the AMP Redirects icon.
+        if (sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true))
+            ampRedirectsPreference.setIcon(R.drawable.modify_url_enabled)
+        else
+            ampRedirectsPreference.setIcon(R.drawable.modify_url_disabled)
+
+        // Set the search custom URL icon.
+        if (searchCustomURLPreference.isEnabled)
+            searchCustomURLPreference.setIcon(R.drawable.search_custom_enabled)
+        else
+            searchCustomURLPreference.setIcon(R.drawable.search_custom_ghosted)
+
+        // Set the proxy icons according to the theme and status.
+        if (proxyString == 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
+                proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted)
+        }
+
+        // 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 hide app bar icon.
+            if (sharedPreferences.getBoolean(getString(R.string.hide_app_bar_key), 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 icon.
+        if (clearEverything) {
+            clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled)
+        } else {
+            clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled)
+        }
+
+        // Set the clear cookies icon.
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_cookies_key), true))
+            clearCookiesPreference.setIcon(R.drawable.clear_cookies_enabled)
+        else
+            clearCookiesPreference.setIcon(R.drawable.clear_cookies_disabled)
+
+        // Set the clear DOM storage icon.
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_dom_storage_key), true))
+            clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_enabled)
+        else
+            clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_disabled)
+
+        // Set the clear form data icon if the API < 26.  It has no effect on newer versions of Android.
+        if (Build.VERSION.SDK_INT < 26) {
+            if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_form_data_key), true))
+                clearFormDataPreference.setIcon(R.drawable.clear_form_data_enabled)
+            else
+                clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled)
+        }
+
+        // Set the clear logcat 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)
+
+        // Set the clear cache icon.
+        if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_cache_key), true))
+            clearCachePreference.setIcon(R.drawable.clear_cache_enabled)
+        else
+            clearCachePreference.setIcon(R.drawable.clear_cache_disabled)
+
+        // Set the open intents in new tab icon.
+        if (sharedPreferences.getBoolean(getString(R.string.open_intents_in_new_tab_key), true))
+            openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled)
+        else
+            openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled)
+
+        // Set the swipe to refresh icon.
+        if (sharedPreferences.getBoolean(getString(R.string.swipe_to_refresh_key), true))
+            swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled)
+        else
+            swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled)
+
+        // Set the download with external app 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)
+
+        // Set the scroll app bar 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)
+
+        // Set the bottom app bar 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)
+
+        // Set the display additional app bar icons 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)
+
+        // Set the WebView theme icon.
+        if (webViewThemePreference.isEnabled) {  // The WebView theme preference is enabled.
+            when (webViewThemeEntryNumber) {
+                // The system default WebView theme is selected.
+                0 -> {
+                    // Get the current theme status.
+                    val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+
+                    // 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)
+                }
+
+                // The light WebView theme is selected.
+                1 -> {
+                    // Set the icon.
+                    webViewThemePreference.setIcon(R.drawable.webview_light_theme)
+                }
+
+                // The dark WebView theme is selected.
+                2 -> {
+                    // Set the icon.
+                    webViewThemePreference.setIcon(R.drawable.webview_dark_theme)
+                }
+            }
+        } else {  // The WebView theme preference is disabled.
+            webViewThemePreference.setIcon(R.drawable.webview_theme_ghosted)
+        }
+
+        // Set the wide viewport icon.
+        if (sharedPreferences.getBoolean(getString(R.string.wide_viewport_key), true))
+            wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled)
+        else
+            wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled)
+
+        // Set the display webpage images icon.
+        if (sharedPreferences.getBoolean(getString(R.string.display_webpage_images_key), true))
+            displayWebpageImagesPreference.setIcon(R.drawable.images_enabled)
+        else
+            displayWebpageImagesPreference.setIcon(R.drawable.images_disabled)
+    }
+
+    // The listener should be unregistered when the app is paused.
+    override fun onPause() {
+        // Run the default commands.
+        super.onPause()
+
+        // Get a handle for the shared preferences.
+        val sharedPreferences = preferenceScreen.sharedPreferences!!
+
+        // Unregister the shared preference listener.
+        sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
+    }
+
+    // The listener should be re-registered when the app is resumed.
+    override fun onResume() {
+        // Run the default commands.
+        super.onResume()
+
+        // Get a new shared preference change listener.
+        sharedPreferenceChangeListener = getSharedPreferenceChangeListener()
+
+        // Get a handle for the shared preferences.
+        val sharedPreferences = preferenceScreen.sharedPreferences!!
+
+        // Re-register the shared preference listener.
+        sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
+    }
+
+    private fun getSharedPreferenceChangeListener(): OnSharedPreferenceChangeListener {
+        // Return the shared preference change listener.
+        return OnSharedPreferenceChangeListener { sharedPreferences: SharedPreferences, key: String? ->
+            when (key) {
+                getString(R.string.javascript_key) -> {
+                    // Update the icons and the DOM storage preference status.
+                    if (sharedPreferences.getBoolean(getString(R.string.javascript_key), 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.isEnabled = true
+
+                        // Update the icon for the DOM storage preference.
+                        if (sharedPreferences.getBoolean(getString(R.string.dom_storage_key), false))
+                            domStoragePreference.setIcon(R.drawable.dom_storage_enabled)
+                        else
+                            domStoragePreference.setIcon(R.drawable.dom_storage_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.isEnabled = false
+
+                        // Set the icon for DOM storage preference to be ghosted.
+                        domStoragePreference.setIcon(R.drawable.dom_storage_ghosted)
+                    }
+                }
+
+                getString(R.string.cookies_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.cookies_key), false))
+                        cookiesPreference.setIcon(R.drawable.cookies_enabled)
+                    else
+                        cookiesPreference.setIcon(R.drawable.cookies_disabled)
+                }
+
+                getString(R.string.dom_storage_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.dom_storage_key), false))
+                        domStoragePreference.setIcon(R.drawable.dom_storage_enabled)
+                    else
+                        domStoragePreference.setIcon(R.drawable.dom_storage_disabled)
+                }
+
+                getString(R.string.save_form_data_key) -> {  // Saved form data can be removed once the minimum API >= 26.
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.save_form_data_key), false))
+                        formDataPreference.setIcon(R.drawable.form_data_enabled)
+                    else
+                        formDataPreference.setIcon(R.drawable.form_data_disabled)
+                }
+
+                getString(R.string.user_agent_key) -> {
+                    // Get the new user agent name.
+                    val newUserAgentName = sharedPreferences.getString(getString(R.string.user_agent_key), getString(R.string.user_agent_default_value))
+
+                    // Get the array position for the new user agent name.
+                    val newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName)
+
+                    // Get the translated new user agent name.
+                    val translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition]
+
+                    // Populate the user agent summary.
+                    when (newUserAgentArrayPosition) {
+                        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.summary = "$translatedNewUserAgentName:\n$defaultUserAgent"
+
+                            // Disable the custom user agent preference.
+                            customUserAgentPreference.isEnabled = false
+
+                            // Set the custom user agent preference icon.
+                            customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted)
+                        }
+
+                        MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT -> {
+                            // Set the summary text.
+                            userAgentPreference.setSummary(R.string.custom_user_agent)
+
+                            // Enable the custom user agent preference.
+                            customUserAgentPreference.isEnabled = true
+
+                            // Set the custom user agent preference icon.
+                            customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled)
+                        }
+
+                        else -> {
+                            // Get the user agent summary from the user agent data array.
+                            userAgentPreference.summary = "$translatedNewUserAgentName:\n${userAgentDataArray[newUserAgentArrayPosition]}"
+
+                            // Disable the custom user agent preference.
+                            customUserAgentPreference.isEnabled = false
+
+                            // Set the custom user agent preference icon.
+                            customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted)
+                        }
+                    }
+                }
+
+                getString(R.string.custom_user_agent_key) -> {
+                    // Set the new custom user agent as the summary text for the preference.
+                    customUserAgentPreference.summary = sharedPreferences.getString(getString(R.string.custom_user_agent_key), getString(R.string.custom_user_agent_default_value))
+                }
+
+                getString(R.string.x_requested_with_header_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.x_requested_with_header_key), true))
+                        xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_enabled)
+                    else
+                        xRequestedWithHeaderPreference.setIcon(R.drawable.x_requested_with_header_disabled)
+
+                    // Restart Privacy Browser.
+                    restartPrivacyBrowser()
+                }
+
+                getString(R.string.incognito_mode_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.incognito_mode_key), false))
+                        incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled)
+                    else
+                        incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled)
+                }
+
+                getString(R.string.allow_screenshots_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(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()
+                }
+
+                getString(R.string.easylist_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.easylist_key), true))
+                        easyListPreference.setIcon(R.drawable.block_ads_enabled)
+                    else
+                        easyListPreference.setIcon(R.drawable.block_ads_disabled)
+                }
+
+                getString(R.string.easyprivacy_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.easyprivacy_key), true))
+                        easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled)
+                    else
+                        easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled)
+                }
+
+                getString(R.string.fanboys_annoyance_list_key) -> {
+                    // Get the current Fanboy settings.
+                    val currentFanboyAnnoyanceList = sharedPreferences.getBoolean(getString(R.string.fanboys_annoyance_list_key), true)
+                    val currentFanboySocialBlockingList = sharedPreferences.getBoolean(getString(R.string.fanboys_social_blocking_list_key), 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)
+                    }
+
+                    // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
+                    fanboySocialBlockingListPreference.isEnabled = !currentFanboyAnnoyanceList
+                }
+
+                getString(R.string.fanboys_social_blocking_list_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.fanboys_social_blocking_list_key), true))
+                        fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled)
+                    else
+                        fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled)
+                }
+
+                getString(R.string.ultralist_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.ultralist_key), true))
+                        ultraListPreference.setIcon(R.drawable.block_ads_enabled)
+                    else
+                        ultraListPreference.setIcon(R.drawable.block_ads_disabled)
+                }
+
+                getString(R.string.ultraprivacy_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.ultraprivacy_key), true))
+                        ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled)
+                    else
+                        ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled)
+                }
+
+                getString(R.string.block_all_third_party_requests_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.block_all_third_party_requests_key), false)) {
+                        blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled)
+                    } else {
+                        blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled)
+                    }
+                }
+
+                getString(R.string.tracking_queries_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true))
+                        trackingQueriesPreference.setIcon(R.drawable.modify_url_enabled)
+                    else
+                        trackingQueriesPreference.setIcon(R.drawable.modify_url_disabled)
+                }
+
+                getString(R.string.amp_redirects_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true))
+                        ampRedirectsPreference.setIcon(R.drawable.modify_url_enabled)
+                    else
+                        ampRedirectsPreference.setIcon(R.drawable.modify_url_disabled)
+                }
+
+                getString(R.string.search_key) -> {
+                    // Store the new search string.
+                    val newSearchString = sharedPreferences.getString(getString(R.string.search_key), getString(R.string.search_default_value))
+
+                    // Update the search and search custom URL preferences.
+                    if (newSearchString == getString(R.string.custom_url_item)) {  // A 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.isEnabled = true
+
+                        // Set the search custom URL preference icon.
+                        searchCustomURLPreference.setIcon(R.drawable.search_custom_enabled)
+                    } else {  // A custom URL is not selected.
+                        // Set the summary text to the new search string.
+                        searchPreference.summary = newSearchString
+
+                        // Disable the search custom URL Preference.
+                        searchCustomURLPreference.isEnabled = false
+
+                        // Set the search custom URL preference icon.
+                        searchCustomURLPreference.setIcon(R.drawable.search_custom_ghosted)
+                    }
+                }
+
+                getString(R.string.search_custom_url_key) -> {
+                    // Set the new search custom URL as the summary text for the preference.
+                    searchCustomURLPreference.summary = sharedPreferences.getString(getString(R.string.search_custom_url_key), getString(R.string.search_custom_url_default_value))
+                }
+
+                getString(R.string.proxy_key) -> {
+                    // Get the current proxy string.
+                    val currentProxyString = sharedPreferences.getString(getString(R.string.proxy_key), getString(R.string.proxy_default_value))
+
+                    // Update the proxy preference summary text.
+                    proxyPreference.summary = when (currentProxyString) {
+                        ProxyHelper.NONE -> getString(R.string.no_proxy_enabled)
+                        ProxyHelper.TOR -> getString(R.string.tor_enabled)
+                        ProxyHelper.I2P -> getString(R.string.i2p_enabled)
+                        ProxyHelper.CUSTOM -> getString(R.string.custom_proxy)
+                        else -> getString(R.string.no_proxy_enabled)
+                    }
+
+                    // Update the status of the custom URL preference.
+                    proxyCustomUrlPreference.isEnabled = currentProxyString == ProxyHelper.CUSTOM
+
+                    // Update the icons.
+                    if (currentProxyString == 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
+                            proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted)
+                    }
+                }
+
+                getString(R.string.proxy_custom_url_key) -> {
+                    // Set the summary text for the proxy custom URL.
+                    proxyCustomUrlPreference.summary = sharedPreferences.getString(getString(R.string.proxy_custom_url_key), getString(R.string.proxy_custom_url_default_value))
+                }
+
+                getString(R.string.full_screen_browsing_mode_key) -> {
+                    // Update the icons.
+                    if (sharedPreferences.getBoolean(getString(R.string.full_screen_browsing_mode_key), 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(getString(R.string.hide_app_bar_key), true))
+                            hideAppBarPreference.setIcon(R.drawable.app_bar_enabled)
+                        else
+                            hideAppBarPreference.setIcon(R.drawable.app_bar_disabled)
+                    } else {  // Full screen browsing is disabled.
+                        // Update the icons.
+                        fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled)
+                        hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted)
+                    }
+                }
+
+                getString(R.string.hide_app_bar_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.hide_app_bar_key), true))
+                        hideAppBarPreference.setIcon(R.drawable.app_bar_enabled)
+                    else
+                        hideAppBarPreference.setIcon(R.drawable.app_bar_disabled)
+                }
+
+                getString(R.string.clear_everything_key) -> {
+                    // Store the new clear everything status
+                    val newClearEverythingBoolean = sharedPreferences.getBoolean(getString(R.string.clear_everything_key), true)
+
+                    // Update the status of the clear and exit preferences.
+                    clearCookiesPreference.isEnabled = !newClearEverythingBoolean
+                    clearDomStoragePreference.isEnabled = !newClearEverythingBoolean
+                    clearFormDataPreference.isEnabled = !newClearEverythingBoolean  // Clear form data can be removed once the minimum API >= 26.
+                    clearLogcatPreference.isEnabled = !newClearEverythingBoolean
+                    clearCachePreference.isEnabled = !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(getString(R.string.clear_cookies_key), 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(getString(R.string.clear_dom_storage_key), 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(getString(R.string.clear_form_data_key), true))
+                            clearFormDataPreference.setIcon(R.drawable.clear_form_data_enabled)
+                        else
+                            clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled)
+                    }
+
+                    // Update the clear logcat preference icon.
+                    if (newClearEverythingBoolean || sharedPreferences.getBoolean(getString(R.string.clear_logcat_key), true))
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_enabled)
+                    else
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_disabled)
+
+                    // Update the clear cache preference icon.
+                    if (newClearEverythingBoolean || sharedPreferences.getBoolean(getString(R.string.clear_cache_key), true))
+                        clearCachePreference.setIcon(R.drawable.clear_cache_enabled)
+                    else
+                        clearCachePreference.setIcon(R.drawable.clear_cache_disabled)
+                }
+
+                getString(R.string.clear_cookies_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.clear_cookies_key), true))
+                        clearCookiesPreference.setIcon(R.drawable.clear_cookies_enabled)
+                    else
+                        clearCookiesPreference.setIcon(R.drawable.clear_cookies_disabled)
+                }
+
+                getString(R.string.clear_dom_storage_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.clear_dom_storage_key), true))
+                        clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_enabled)
+                    else
+                        clearDomStoragePreference.setIcon(R.drawable.clear_dom_storage_disabled)
+                }
+
+                getString(R.string.clear_form_data_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.clear_form_data_key), true))
+                        clearFormDataPreference.setIcon(R.drawable.clear_form_data_enabled)
+                    else
+                        clearFormDataPreference.setIcon(R.drawable.clear_form_data_disabled)
+                }
+
+                getString(R.string.clear_logcat_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.clear_logcat_key), true))
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_enabled)
+                    else
+                        clearLogcatPreference.setIcon(R.drawable.clear_logcat_disabled)
+                }
+
+                getString(R.string.clear_cache_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.clear_cache_key), true))
+                        clearCachePreference.setIcon(R.drawable.clear_cache_enabled)
+                    else
+                        clearCachePreference.setIcon(R.drawable.clear_cache_disabled)
+                }
+
+                getString(R.string.homepage_key) -> {
+                    // Set the new homepage URL as the summary text for the Homepage preference.
+                    homepagePreference.summary = sharedPreferences.getString(getString(R.string.homepage_key), getString(R.string.homepage_default_value))
+                }
+
+                getString(R.string.font_size_key) -> {
+                    // Update the font size summary text.
+                    fontSizePreference.summary = sharedPreferences.getString(getString(R.string.font_size_key), getString(R.string.font_size_default_value)) + "%"
+                }
+
+                getString(R.string.open_intents_in_new_tab_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.open_intents_in_new_tab_key), true))
+                        openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled)
+                    else
+                        openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled)
+                }
+
+                getString(R.string.swipe_to_refresh_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.swipe_to_refresh_key), true))
+                        swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled)
+                    else
+                        swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled)
+                }
+
+                getString(R.string.download_with_external_app_key) -> {
+                    // Update the 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)
+                }
+
+                getString(R.string.scroll_app_bar_key) -> {
+                    // Update the 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)
+                }
+
+                getString(R.string.bottom_app_bar_key) -> {
+                    // Update the 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)
+
+                    // Restart Privacy Browser.
+                    restartPrivacyBrowser()
+                }
+
+                getString(R.string.display_additional_app_bar_icons_key) -> {
+                    // Update the 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)
+                }
+
+                getString(R.string.app_theme_key) -> {
+                    // 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.
+                    val appThemeEntryNumber: Int = when (sharedPreferences.getString(getString(R.string.app_theme_key), getString(R.string.app_theme_default_value))) {
+                        appThemeEntryValuesStringArray[1] -> 1  // The light theme is selected.
+                        appThemeEntryValuesStringArray[2] -> 2  // The dark theme is selected.
+                        else -> 0  // The system default theme is selected.
+                    }
+
+                    // Update the system according to the new theme.
+                    when (appThemeEntryNumber) {
+                        0 -> {  // The system default theme is selected.
+                            // Update the theme preference summary text.
+                            appThemePreference.summary = 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)
+                            }
+                        }
+
+                        1 -> {  // The light theme is selected.
+                            // Update the theme preference summary text.
+                            appThemePreference.summary = appThemeEntriesStringArray[1]
+
+                            // Apply the new theme.
+                            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
+                        }
+
+                        2 -> {  // The dark theme is selected.
+                            // Update the theme preference summary text.
+                            appThemePreference.summary = appThemeEntriesStringArray[2]
+
+                            // Apply the new theme.
+                            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
+                        }
+                    }
+
+                    // Enable the WebView theme preference if the API < 33 or the app theme is set to light.
+                    webViewThemePreference.isEnabled = ((Build.VERSION.SDK_INT < 33) || (appThemeEntryNumber != 1))
+
+                    // Get the webView theme entry number that matches the new WebView theme.
+                    val webViewThemeEntryNumber: Int = when (sharedPreferences.getString(getString(R.string.webview_theme_key), getString(R.string.webview_theme_default_value))) {
+                        webViewThemeEntriesStringArray[1] -> 1  // The light theme is selected.
+                        webViewThemeEntryValuesStringArray[2] -> 2  // The dark theme is selected.
+                        else -> 0  // The system default theme is selected.
+                    }
+
+                    // Update the WebView theme icon.
+                    if (webViewThemePreference.isEnabled) {  // The WebView theme preference is enabled.
+                        when (webViewThemeEntryNumber) {
+                            // The system default WebView theme is selected.
+                            0 -> {
+                                // Get the current theme status.
+                                val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+
+                                // 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)
+                            }
+
+                            // The light WebView theme is selected.
+                            1 -> {
+                                // Set the icon.
+                                webViewThemePreference.setIcon(R.drawable.webview_light_theme)
+                            }
+
+                            // The dark WebView theme is selected.
+                            2 -> {
+                                // Set the icon.
+                                webViewThemePreference.setIcon(R.drawable.webview_dark_theme)
+                            }
+                        }
+                    } else {  // The WebView theme preference is disabled.
+                        webViewThemePreference.setIcon(R.drawable.webview_theme_ghosted)
+                    }
+                }
+
+                getString(R.string.webview_theme_key) -> {
+                    // Get the webView theme entry number that matches the new WebView theme.
+                    val newWebViewThemeEntryNumber: Int = when (sharedPreferences.getString(getString(R.string.webview_theme_key), getString(R.string.webview_theme_default_value))) {
+                        webViewThemeEntriesStringArray[1] -> 1  // The light theme is selected.
+                        webViewThemeEntryValuesStringArray[2] -> 2  // The dark theme is selected.
+                        else -> 0  // The system default theme is selected.
+                    }
+
+                    // Update the WebView theme icon.
+                    when (newWebViewThemeEntryNumber) {
+                        // The system default WebView theme is selected.
+                        0 -> {
+                            // Get the current theme status.
+                            val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+
+                            // 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)
+                        }
+
+                        // The light WebView theme is selected.
+                        1 -> {
+                            // Set the icon.
+                            webViewThemePreference.setIcon(R.drawable.webview_light_theme)
+                        }
+
+                        // The dark WebView theme is selected.
+                        2 -> {
+                            // Set the icon.
+                            webViewThemePreference.setIcon(R.drawable.webview_dark_theme)
+                        }
+                    }
+
+                    // Set the current theme as the summary text for the preference.
+                    webViewThemePreference.summary = webViewThemeEntriesStringArray[newWebViewThemeEntryNumber]
+                }
+
+                getString(R.string.wide_viewport_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.wide_viewport_key), true))
+                        wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled)
+                    else
+                        wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled)
+                }
+
+                getString(R.string.display_webpage_images_key) -> {
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean(getString(R.string.display_webpage_images_key), true))
+                        displayWebpageImagesPreference.setIcon(R.drawable.images_enabled)
+                    else
+                        displayWebpageImagesPreference.setIcon(R.drawable.images_disabled)
+                }
+            }
+        }
+    }
+
+    private fun restartPrivacyBrowser() {
+        // Create an intent to restart Privacy Browser.
+        val restartIntent = requireActivity().parentActivityIntent!!
+
+        // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack.  It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
+        restartIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+
+        // Create a handler to restart the activity.
+        val restartHandler = Handler(Looper.getMainLooper())
+
+        // Create a runnable to restart the activity.
+        val restartRunnable = Runnable {
+            // Restart the activity.
+            startActivity(restartIntent)
+
+            // Kill this instance of Privacy Browser.  Otherwise, the app exhibits sporadic behavior after the restart.
+            exitProcess(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)
+    }
+}
index c5401d457fedd318904f0292bcd4f43f4cf5b144..98969343de63f8c3fb78c856bb416a4fa62c6a58 100644 (file)
@@ -318,17 +318,17 @@ class DomainsDatabaseHelper(private val appContext: Context) : SQLiteOpenHelper(
         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext)
 
         // Get the default settings.
-        val javaScript = sharedPreferences.getBoolean("javascript", false)
+        val javaScript = sharedPreferences.getBoolean(appContext.getString(R.string.javascript_key), false)
         val cookies = sharedPreferences.getBoolean(appContext.getString(R.string.cookies_key), false)
-        val domStorage = sharedPreferences.getBoolean("dom_storage", false)
-        val saveFormData = sharedPreferences.getBoolean("save_form_data", false) // Form data can be removed once the minimum API >= 26.
-        val easyList = sharedPreferences.getBoolean("easylist", true)
-        val easyPrivacy = sharedPreferences.getBoolean("easyprivacy", true)
-        val fanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true)
-        val fanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true)
-        val ultraList = sharedPreferences.getBoolean("ultralist", true)
-        val ultraPrivacy = sharedPreferences.getBoolean("ultraprivacy", true)
-        val blockAllThirdPartyRequests = sharedPreferences.getBoolean("block_all_third_party_requests", false)
+        val domStorage = sharedPreferences.getBoolean(appContext.getString(R.string.dom_storage_key), false)
+        val saveFormData = sharedPreferences.getBoolean(appContext.getString(R.string.save_form_data_key), false)  // Form data can be removed once the minimum API >= 26.
+        val easyList = sharedPreferences.getBoolean(appContext.getString(R.string.easylist_key), true)
+        val easyPrivacy = sharedPreferences.getBoolean(appContext.getString(R.string.easyprivacy_key), true)
+        val fanboyAnnoyanceList = sharedPreferences.getBoolean(appContext.getString(R.string.fanboys_annoyance_list_key), true)
+        val fanboySocialBlockingList = sharedPreferences.getBoolean(appContext.getString(R.string.fanboys_social_blocking_list_key), true)
+        val ultraList = sharedPreferences.getBoolean(appContext.getString(R.string.ultralist_key), true)
+        val ultraPrivacy = sharedPreferences.getBoolean(appContext.getString(R.string.ultraprivacy_key), true)
+        val blockAllThirdPartyRequests = sharedPreferences.getBoolean(appContext.getString(R.string.block_all_third_party_requests_key), false)
 
         // Create entries for the database fields.  The ID is created automatically.  The pinned SSL certificate information is not created unless added by the user.
         domainContentValues.put(DOMAIN_NAME, domainName)
@@ -343,7 +343,7 @@ class DomainsDatabaseHelper(private val appContext: Context) : SQLiteOpenHelper(
         domainContentValues.put(ULTRALIST, ultraList)
         domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacy)
         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests)
-        domainContentValues.put(USER_AGENT, "System default user agent")
+        domainContentValues.put(USER_AGENT, appContext.getString(R.string.user_agent_default_value))
         domainContentValues.put(X_REQUESTED_WITH_HEADER, 0)
         domainContentValues.put(FONT_SIZE, 0)
         domainContentValues.put(SWIPE_TO_REFRESH, 0)
index d83f96d6e8acab75fd25e4e7e6239ec93673e6ea..c11ee8b9d0dcc88e8e1c2280949df6e8dc379f14 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2019-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2019-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
 
@@ -54,4 +54,4 @@
             android:layout_marginBottom="5dp"
             android:layout_gravity="end" />
     </LinearLayout>
-</ScrollView>
\ No newline at end of file
+</ScrollView>
diff --git a/app/src/main/res/layout/settings_bottom_appbar.xml b/app/src/main/res/layout/settings_bottom_appbar.xml
new file mode 100644 (file)
index 0000000..0163886
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
+
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+
+  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 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 Android.  If not, see <http://www.gnu.org/licenses/>. -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent" >
+
+    <!-- The linear layout with `orientation="vertical"` moves the app bar layout below the main content. -->
+    <LinearLayout
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:orientation="vertical" >
+
+        <!-- Preferences FrameLayout. -->
+        <FrameLayout
+            android:id="@+id/preferences_framelayout"
+            android:layout_height="0dp"
+            android:layout_width="match_parent"
+            android:layout_weight="1"/>
+
+        <!-- The app bar theme must be specified here because the activity uses a `NoActionBar` theme. -->
+        <com.google.android.material.appbar.AppBarLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:background="?android:attr/colorBackground"
+            android:theme="@style/PrivacyBrowserAppBar" >
+
+            <androidx.appcompat.widget.Toolbar
+                android:id="@+id/toolbar"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent" />
+        </com.google.android.material.appbar.AppBarLayout>
+    </LinearLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/settings_top_appbar.xml b/app/src/main/res/layout/settings_top_appbar.xml
new file mode 100644 (file)
index 0000000..ec5dc3f
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
+
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+
+  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 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 Android.  If not, see <http://www.gnu.org/licenses/>. -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent" >
+
+    <!-- The linear layout with `orientation="vertical"` moves the main content below the app bar layout. -->
+    <LinearLayout
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:orientation="vertical" >
+
+        <!-- The app bar theme must be specified here because the activity uses a `NoActionBar` theme. -->
+        <com.google.android.material.appbar.AppBarLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:background="?android:attr/colorBackground"
+            android:theme="@style/PrivacyBrowserAppBar" >
+
+            <androidx.appcompat.widget.Toolbar
+                android:id="@+id/toolbar"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent" />
+        </com.google.android.material.appbar.AppBarLayout>
+
+        <!-- Preferences FrameLayout. -->
+        <FrameLayout
+            android:id="@+id/preferences_framelayout"
+            android:layout_height="match_parent"
+            android:layout_width="match_parent" />
+    </LinearLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
index b4bded4fce2ab8ab92a99a0d452a5b2f53590f13..f996c45e86a8f8ef1018ae0a3e06f2c7faf3f37f 100644 (file)
             <string name="mebibyte">MiB</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance Sperrliste:</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking Sperrliste:</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance Sperrliste:</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking Sperrliste:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Paket-Signatur</string>
index 91c76b220bcf1266730e43e0dc2502476c29c5c9..a9ece5714c86de141436835a2241916abf6b810f 100644 (file)
             <string name="mebibyte">MiB</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Lista molesta de Fanboy:</string>
-            <string name="fanboy_social_label">Lista de bloqueo social de Fanboy:</string>
+            <string name="fanboys_annoyance_label">Lista molesta de Fanboy:</string>
+            <string name="fanboys_social_label">Lista de bloqueo social de Fanboy:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">Ultra Privacidad:</string>
         <string name="package_signature">Firma del paquete</string>
index c49910b560870ba9a33b62d5f352c26dfd9eb3aa..fffcfc1121a2babcf17aaabbf5720926d49edab5 100644 (file)
             <string name="mebibyte">Mio</string>
             <string name="easylist_label">EasyList :</string>
             <string name="easyprivacy_label">EasyPrivacy :</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance List :</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking List :</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance List :</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking List :</string>
             <string name="ultralist_label">UltraList :</string>
             <string name="ultraprivacy_label">UltraPrivacy :</string>
         <string name="package_signature">Signature de paquets</string>
index 6fcb5022d81ecff1d5d19237c46d0be2f1b151b4..f0b7fc9f7b94b7954982d126112535673bb72a09 100644 (file)
             <string name="mebibyte">MiB</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance List:</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking List:</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance List:</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking List:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Firma del Pacchetto</string>
index 3e505dbe979b87caa1e08eda653c508cec21f3b6..d998db6b08f2c37c9bcb4d88d96c1a753161afec 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2015-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
 
         <item name="android:textColorHighlight">@color/violet_700</item>
     </style>
 
-    <style name="PrivacyBrowserSettings" parent="Theme.AppCompat.DayNight" >
-        <!-- Main Items. -->
-        <item name="android:navigationBarColor">?android:attr/colorBackground</item>
-        <item name="android:statusBarColor">?android:attr/colorBackground</item>
-        <item name="android:windowLightNavigationBar">?attr/isLightTheme</item>
-        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
-
-        <!-- Colors. -->
-        <item name="colorAccent">@color/violet_500</item>
-        <item name="colorPrimary">?android:attr/colorBackground</item>  <!-- `colorPrimary` sets the background color of the app bar. -->
-    </style>
-
     <style name="PrivacyBrowserAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert" >
         <!-- Colors. -->
         <item name="colorAccent">@color/violet_500</item>
     </style>
-</resources>
\ No newline at end of file
+</resources>
index 77e1470a1c1be4cdfba530f8e962d52185f96094..483ab90aafb8420ca2f6bf323834ba0a7b92223c 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2015-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
 
         <item name="android:textColorHighlight">@color/violet_700</item>
     </style>
 
-    <style name="PrivacyBrowserSettings" parent="Theme.AppCompat.DayNight" >
-        <!-- Main Items. -->
-        <item name="android:statusBarColor">?android:attr/colorBackground</item>
-        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
-
-        <!-- Colors. -->
-        <item name="colorAccent">@color/violet_500</item>
-        <item name="colorPrimary">?android:attr/colorBackground</item>  <!-- `colorPrimary` sets the background color of the app bar. -->
-    </style>
-
     <style name="PrivacyBrowserAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert" >
         <!-- Colors. -->
         <item name="colorAccent">@color/violet_500</item>
     </style>
-</resources>
\ No newline at end of file
+</resources>
index 4330292b5a780547f988f80daaa0f3379b0652d4..219ec1995513f6101cbb8bfc7874132aaadb4e0a 100644 (file)
             <string name="mebibyte">MiB</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance List:</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking List:</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance List:</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking List:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Assinatura do Pacote</string>
index b6589d6d2655fdb272a6240c2e17739bf2030fbb..04744f5e0fcdabf7db99dc449b9e77f5e6d6054d 100644 (file)
             <string name="mebibyte">МиБ</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance List:</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking List:</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance List:</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking List:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Подпись пакета</string>
index 5c3bc78d72a9cacad6fd97b4b3fd73c38361dec1..7ecc45580bd44db5e43425cdb31550f5cfe8534b 100644 (file)
             <string name="openkeychain">OpenKeychain:</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance List:</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking List:</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance List:</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking List:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Paket İmzası</string>
index e9833d6fb84e7bba693e2c1b804b7003f363564a..82b618fb34968b5375cfa8f1f63b888ff943f907 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2015-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
 
         <item name="android:textColorHighlight">@color/blue_200</item>
     </style>
 
-    <style name="PrivacyBrowserSettings" parent="Theme.AppCompat.DayNight" >
-        <!-- Main Items. -->
-        <item name="android:navigationBarColor">?android:attr/colorBackground</item>
-        <item name="android:statusBarColor">?android:attr/colorBackground</item>
-        <item name="android:windowLightNavigationBar">?attr/isLightTheme</item>
-        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
-
-        <!-- Colors. -->
-        <item name="colorAccent">@color/blue_700</item>
-        <item name="colorPrimary">?android:attr/colorBackground</item>  <!-- `colorPrimary` sets the background color of the app bar. -->
-    </style>
-
     <style name="PrivacyBrowserAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert" >
         <!-- Colors. -->
         <item name="colorAccent">@color/blue_700</item>
     </style>
-</resources>
\ No newline at end of file
+</resources>
index 676f7554e0482d34185c76f50331a7b944edaf63..6ff8f67567dbe9e1d5f1e012ba4ab611156f9328 100644 (file)
             <string name="mebibyte">MiB</string>
             <string name="easylist_label">EasyList:</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
-            <string name="fanboy_annoyance_label">Fanboy’s Annoyance List:</string>
-            <string name="fanboy_social_label">Fanboy’s Social Blocking List:</string>
+            <string name="fanboys_annoyance_label">Fanboy’s Annoyance List:</string>
+            <string name="fanboys_social_label">Fanboy’s Social Blocking List:</string>
             <string name="ultralist_label">UltraList:</string>
             <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Package Signature</string>
             <item>https://search.yahoo.com/mobile/s?p=</item>
             <item>Custom URL</item>  <!-- This item must not be translated into other languages because it is referenced in code.  It is never displayed on the screen. -->
         </string-array>
+        <string name="custom_url_item" translatable="false">Custom URL</string>
         <string name="custom_url">Custom URL</string>
         <string name="search_custom_url">Search custom URL</string>
     <string name="proxy">Proxy</string>
     <!-- Non-translatable preference keys. -->
     <string name="allow_screenshots_key" translatable="false">allow_screenshots</string>
     <string name="amp_redirects_key" translatable="false">amp_redirects</string>
+    <string name="app_theme_key" translatable="false">app_theme</string>
+    <string name="block_all_third_party_requests_key" translatable="false">block_all_third_party_requests</string>
     <string name="bottom_app_bar_key" translatable="false">bottom_app_bar</string>
     <string name="cookies_key" translatable="false">cookies</string>
+    <string name="clear_and_exit_category_key" translatable="false">clear_and_exit</string>
+    <string name="clear_cache_key" translatable="false">clear_cache</string>
+    <string name="clear_cookies_key" translatable="false">clear_cookies</string>
+    <string name="clear_dom_storage_key" translatable="false">clear_dom_storage</string>
+    <string name="clear_everything_key" translatable="false">clear_everything</string>
+    <string name="clear_form_data_key" translatable="false">clear_form_data</string>  <!-- The clear form data string can be removed once the minimum API >= 26. -->
     <string name="clear_logcat_key" translatable="false">clear_logcat</string>
     <string name="custom_user_agent_key" translatable="false">custom_user_agent</string>
     <string name="display_additional_app_bar_icons_key" translatable="false">display_additional_app_bar_icons</string>
     <string name="display_webpage_images_key" translatable="false">display_webpage_images</string>
+    <string name="dom_storage_key" translatable="false">dom_storage</string>
     <string name="download_with_external_app_key" translatable="false">download_with_external_app</string>
+    <string name="easylist_key" translatable="false">easylist</string>
+    <string name="easyprivacy_key" translatable="false">easyprivacy</string>
+    <string name="fanboys_annoyance_list_key" translatable="false">fanboys_annoyance_list</string>
+    <string name="fanboys_social_blocking_list_key" translatable="false">fanboys_social_blocking_list</string>
     <string name="font_size_key" translatable="false">font_size</string>
+    <string name="full_screen_browsing_mode_key" translatable="false">full_screen_browsing_mode</string>
+    <string name="hide_app_bar_key" translatable="false">hide_app_bar</string>
+    <string name="homepage_key" translatable="false">homepage</string>
+    <string name="incognito_mode_key" translatable="false">incognito_mode</string>
+    <string name="javascript_key" translatable="false">javascript</string>
+    <string name="open_intents_in_new_tab_key" translatable="false">open_intents_in_new_tab</string>
+    <string name="privacy_category_key" translatable="false">privacy</string>
+    <string name="proxy_key" translatable="false">proxy</string>
     <string name="proxy_custom_url_key" translatable="false">proxy_custom_url</string>
+    <string name="save_form_data_key" translatable="false">save_form_data</string>  <!--The form data string can be removed once the minimum API >= 26. -->
     <string name="scroll_app_bar_key" translatable="false">scroll_app_bar</string>
+    <string name="search_custom_url_key" translatable="false">search_custom_url</string>
+    <string name="search_key" translatable="false">search</string>
     <string name="swipe_to_refresh_key" translatable="false">swipe_to_refresh</string>
     <string name="tracking_queries_key" translatable="false">tracking_queries</string>
+    <string name="ultralist_key" translatable="false">ultralist</string>
+    <string name="ultraprivacy_key" translatable="false">ultraprivacy</string>
     <string name="user_agent_key" translatable="false">user_agent</string>
     <string name="webview_theme_key" translatable="false">webview_theme</string>
     <string name="wide_viewport_key" translatable="false">wide_viewport</string>
index 6a79f0ba0c5d9d3efc708b62045c2a7fc119994a..f3a7411e3edeb4ce465d7c12d57d787c86759c29 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2015-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
 
         <item name="android:textColorHighlight">@color/blue_200</item>
     </style>
 
-    <style name="PrivacyBrowserSettings" parent="Theme.AppCompat.DayNight" >
-        <!-- Main Items. -->
-        <item name="android:statusBarColor">?android:attr/colorBackground</item>
-        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
-
-        <!-- Colors. -->
-        <item name="colorAccent">@color/blue_700</item>
-        <item name="colorPrimary">?android:attr/colorBackground</item>  <!-- `colorPrimary` sets the background color of the app bar. -->
-    </style>
-
     <style name="PrivacyBrowserAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert" >
         <!-- Colors. -->
         <item name="colorAccent">@color/blue_700</item>
     </style>
-</resources>
\ No newline at end of file
+</resources>
index 4957727ce100643c1ffe067d966a12902c1470d3..6bb415e24b59ab5ed6c47dd033e5cf529956032e 100644 (file)
     xmlns:android="http://schemas.android.com/apk/res/android" >
 
     <PreferenceCategory
-        android:key="privacy"
+        android:key="@string/privacy_category_key"
         android:title="@string/privacy" >
 
         <SwitchPreference
-            android:key="javascript"
+            android:key="@string/javascript_key"
             android:title="@string/javascript"
             android:summary="@string/javascript_preference_summary"
             android:defaultValue="false" />
             android:defaultValue="false" />
 
         <SwitchPreference
-            android:key="dom_storage"
+            android:key="@string/dom_storage_key"
             android:title="@string/dom_storage_preference"
             android:summary="@string/dom_storage_preference_summary"
             android:defaultValue="false" />
 
         <!-- Save form data can be removed once the minimum API >= 26. -->
         <SwitchPreference
-            android:key="save_form_data"
+            android:key="@string/save_form_data_key"
             android:title="@string/save_form_data_preference"
             android:summary="@string/save_form_data_preference_summary"
             android:defaultValue="false" />
@@ -72,7 +72,7 @@
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="incognito_mode"
+            android:key="@string/incognito_mode_key"
             android:title="@string/incognito_mode"
             android:summary="@string/incognito_mode_summary"
             android:defaultValue="false" />
         android:title="@string/blocklists" >
 
         <SwitchPreference
-            android:key="easylist"
+            android:key="@string/easylist_key"
             android:title="@string/easylist"
             android:summary="@string/easylist_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="easyprivacy"
+            android:key="@string/easyprivacy_key"
             android:title="@string/easyprivacy"
             android:summary="@string/easyprivacy_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="fanboys_annoyance_list"
+            android:key="@string/fanboys_annoyance_list_key"
             android:title="@string/fanboys_annoyance_list"
             android:summary="@string/fanboys_annoyance_list_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="fanboys_social_blocking_list"
+            android:key="@string/fanboys_social_blocking_list_key"
             android:title="@string/fanboys_social_blocking_list"
             android:summary="@string/fanboys_social_blocking_list_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="ultralist"
+            android:key="@string/ultralist_key"
             android:title="@string/ultralist"
             android:summary="@string/ultralist_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="ultraprivacy"
+            android:key="@string/ultraprivacy_key"
             android:title="@string/ultraprivacy"
             android:summary="@string/ultraprivacy_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="block_all_third_party_requests"
+            android:key="@string/block_all_third_party_requests_key"
             android:title="@string/block_all_third_party_requests"
             android:summary="@string/block_all_third_party_requests_summary"
             android:defaultValue="false" />
         android:title="@string/search" >
 
         <ListPreference
-            android:key="search"
+            android:key="@string/search_key"
             android:title="@string/search"
             android:entries="@array/search_entries"
             android:entryValues="@array/search_entry_values"
             android:icon="@drawable/search" />
 
         <EditTextPreference
-            android:key="search_custom_url"
+            android:key="@string/search_custom_url_key"
             android:title="@string/search_custom_url"
             android:defaultValue="@string/search_custom_url_default_value"
             android:inputType="textUri" />
         android:title="@string/proxy" >
 
         <ListPreference
-            android:key="proxy"
+            android:key="@string/proxy_key"
             android:title="@string/proxy"
             android:entries="@array/proxy_entries"
             android:entryValues="@array/proxy_entry_values"
         android:title="@string/full_screen" >
 
         <SwitchPreference
-            android:key="full_screen_browsing_mode"
+            android:key="@string/full_screen_browsing_mode_key"
             android:title="@string/full_screen_browsing_mode"
             android:summary="@string/full_screen_browsing_mode_summary"
             android:defaultValue="false" />
 
         <SwitchPreference
-            android:key="hide_app_bar"
+            android:key="@string/hide_app_bar_key"
             android:title="@string/hide_app_bar"
             android:summary="@string/hide_app_bar_summary"
             android:defaultValue="true" />
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:key="clear_and_exit"
+        android:key="@string/clear_and_exit_category_key"
         android:title="@string/clear_and_exit" >
 
         <SwitchPreference
-            android:key="clear_everything"
+            android:key="@string/clear_everything_key"
             android:title="@string/clear_everything"
             android:summary="@string/clear_everything_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="clear_cookies"
+            android:key="@string/clear_cookies_key"
             android:title="@string/clear_cookies_preference"
             android:summary="@string/clear_cookies_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="clear_dom_storage"
+            android:key="@string/clear_dom_storage_key"
             android:title="@string/clear_dom_storage_preference"
             android:summary="@string/clear_dom_storage_summary"
             android:defaultValue="true" />
 
         <!-- Clear form data can be removed once the minimum API >= 26. -->
         <SwitchPreference
-            android:key="clear_form_data"
+            android:key="@string/clear_form_data_key"
             android:title="@string/clear_form_data_preference"
             android:summary="@string/clear_form_data_summary"
             android:defaultValue="true" />
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="clear_cache"
+            android:key="@string/clear_cache_key"
             android:title="@string/clear_cache"
             android:summary="@string/clear_cache_summary"
             android:defaultValue="true" />
         android:title="@string/general" >
 
         <EditTextPreference
-            android:key="homepage"
+            android:key="@string/homepage_key"
             android:title="@string/homepage"
             android:defaultValue="@string/homepage_default_value"
             android:inputType="textUri"
             android:icon="@drawable/font_size" />
 
         <SwitchPreference
-            android:key="open_intents_in_new_tab"
+            android:key="@string/open_intents_in_new_tab_key"
             android:title="@string/open_intents_in_new_tab"
             android:summary="@string/open_intents_in_new_tab_summary"
             android:defaultValue="true" />
             android:defaultValue="false" />
 
         <ListPreference
-            android:key="app_theme"
+            android:key="@string/app_theme_key"
             android:title="@string/app_theme"
             android:entries="@array/app_theme_entries"
             android:entryValues="@array/app_theme_entry_values"