From: Soren Stoutner Date: Wed, 20 Feb 2019 03:04:01 +0000 (-0700) Subject: Migrate to AndroidX from the Android Support Library. https://redmine.stoutner.com... X-Git-Tag: v2.17~5 X-Git-Url: https://gitweb.stoutner.com/?a=commitdiff_plain;h=ba40295dffd761ccdc95d3b46ca7acbad1f00d5e;p=PrivacyBrowserAndroid.git Migrate to AndroidX from the Android Support Library. https://redmine.stoutner.com/issues/387 --- diff --git a/app/build.gradle b/app/build.gradle index 5c0e7dac..714cd710 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,7 +71,19 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'com.android.support:design:28.0.0' + + // Include the following AndroidX libraries. + implementation 'androidx.arch.core:core-common:2.0.0' + implementation 'androidx.arch.core:core-runtime:2.0.0' + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0' + implementation 'androidx.drawerlayout:drawerlayout:1.0.0' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' + implementation 'androidx.viewpager:viewpager:1.0.0' + + // Include the Google material library. + implementation 'com.google.android.material:material:1.0.0' // Only compile Firebase ads for the free flavor. freeImplementation 'com.google.firebase:firebase-ads:17.1.3' diff --git a/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java b/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java index 94f8a91e..c0cf9721 100644 --- a/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java +++ b/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner . + * Copyright © 2018-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -21,17 +21,20 @@ package com.stoutner.privacybrowser.dialogs; import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Build; import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.AdConsentDatabaseHelper; import com.stoutner.privacybrowser.helpers.AdHelper; public class AdConsentDialog extends DialogFragment { + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use a builder to create the alert dialog. @@ -46,8 +49,11 @@ public class AdConsentDialog extends DialogFragment { dialogBuilder.setIcon(R.drawable.block_ads_enabled_light); } + // Remove the incorrect lint warning below that `getApplicationContext()` might be null. + assert getActivity() != null; + // Initialize the bookmarks database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `AdConsentDatabaseHelper`. - // `getContext()` can be used instead of `getActivity.getApplicationContext()` on the minimum API >= 23. + // `getContext()` can be used instead of `getActivity.getApplicationContext()` when the minimum API >= 23. AdConsentDatabaseHelper adConsentDatabaseHelper = new AdConsentDatabaseHelper(getActivity().getApplicationContext(), null, null, 0); // Set the title. @@ -88,8 +94,11 @@ public class AdConsentDialog extends DialogFragment { // Close Privacy Browser Free if the dialog is cancelled without selecting a button (by tapping on the background). @Override public void onCancel(DialogInterface dialogInterface) { + // Remove the incorrect lint warning below that `getApplicationContext()` might be null. + assert getActivity() != null; + // Initialize the bookmarks database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `AdConsentDatabaseHelper`. - // `getContext()` can be used instead of `getActivity.getApplicationContext()` on the minimum API >= 23. + // `getContext()` can be used instead of `getActivity.getApplicationContext()` when the minimum API >= 23. AdConsentDatabaseHelper adConsentDatabaseHelper = new AdConsentDatabaseHelper(getActivity().getApplicationContext(), null, null, 0); // Update the ad consent database. diff --git a/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java b/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java index 7de4e522..c3aae5d4 100644 --- a/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java +++ b/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -19,13 +19,14 @@ package com.stoutner.privacybrowser.helpers; -import android.app.DialogFragment; -import android.app.FragmentManager; import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.RelativeLayout; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + import com.google.ads.mediation.admob.AdMobAdapter; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdSize; @@ -37,7 +38,7 @@ import com.stoutner.privacybrowser.dialogs.AdConsentDialog; public class AdHelper { private static boolean initialized; - public static void initializeAds (View view, Context applicationContext, FragmentManager fragmentManager, String googleAppId, String adUnitId) { + public static void initializeAds(View view, Context applicationContext, FragmentManager fragmentManager, String googleAppId, String adUnitId) { if (!initialized) { // This is the first run. // Initialize mobile ads. MobileAds.initialize(applicationContext, googleAppId); @@ -66,7 +67,7 @@ public class AdHelper { } } - public static void loadAd (View view, Context applicationContext, String adUnitId) { + public static void loadAd(View view, Context applicationContext, String adUnitId) { // Cast the generic view to an AdView. AdView adView = (AdView) view; diff --git a/app/src/free/res/layout/main_webview.xml b/app/src/free/res/layout/main_webview.xml index 48e12f03..53fd4652 100644 --- a/app/src/free/res/layout/main_webview.xml +++ b/app/src/free/res/layout/main_webview.xml @@ -1,7 +1,7 @@ - - + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9e443d8f..625833fe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -67,7 +67,7 @@ diff --git a/app/src/main/assets/de/about_licenses_dark.html b/app/src/main/assets/de/about_licenses_dark.html index 26e7b4bd..3b458ae2 100644 --- a/app/src/main/assets/de/about_licenses_dark.html +++ b/app/src/main/assets/de/about_licenses_dark.html @@ -33,7 +33,7 @@

Privacy Browser ist veröffentlicht unter der GPLv3+ Lizenz. The full text of the license is below. The source code is available from git.stoutner.com.

-

Block Lists

+

Blocklists

EasyList and EasyPrivacy are dual licensed under the GPLv3+ and the Creative Commons Attribution-ShareAlike 3.0+ Unported licenses. @@ -46,8 +46,9 @@

More information about the blocklists can be found on the EasyList website.

Libraries

-

Privacy Browser is built with the Android Support Library, - which is released under the Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

The free flavor of Privacy Browser is built with Firebase Ads, which is released under the Android Software Development Kit License.

diff --git a/app/src/main/assets/de/about_licenses_light.html b/app/src/main/assets/de/about_licenses_light.html index 6592f4f3..6df4e523 100644 --- a/app/src/main/assets/de/about_licenses_light.html +++ b/app/src/main/assets/de/about_licenses_light.html @@ -32,7 +32,7 @@

Privacy Browser ist veröffentlicht unter der GPLv3+ Lizenz. The full text of the license is below. The source code is available from git.stoutner.com.

-

Block Lists

+

Blocklists

EasyList and EasyPrivacy are dual licensed under the GPLv3+ and the Creative Commons Attribution-ShareAlike 3.0+ Unported licenses. @@ -45,8 +45,9 @@

More information about the blocklists can be found on the EasyList website.

Libraries

-

Privacy Browser is built with the Android Support Library, - which is released under the Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

The free flavor of Privacy Browser is built with Firebase Ads, which is released under the Android Software Development Kit License.

diff --git a/app/src/main/assets/en/about_licenses_dark.html b/app/src/main/assets/en/about_licenses_dark.html index da0defc4..fb7fb8a5 100644 --- a/app/src/main/assets/en/about_licenses_dark.html +++ b/app/src/main/assets/en/about_licenses_dark.html @@ -31,7 +31,7 @@

Privacy Browser is released under the GPLv3+ license. The full text of the license is below. The source code is available from git.stoutner.com.

-

Block Lists

+

Blocklists

EasyList and EasyPrivacy are dual licensed under the GPLv3+ and the Creative Commons Attribution-ShareAlike 3.0+ Unported licenses. @@ -44,8 +44,9 @@

More information about the blocklists can be found on the EasyList website.

Libraries

-

Privacy Browser is built with the Android Support Library, - which is released under the Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

The free flavor of Privacy Browser is built with Firebase Ads, which is released under the Android Software Development Kit License.

diff --git a/app/src/main/assets/en/about_licenses_light.html b/app/src/main/assets/en/about_licenses_light.html index 5ecac0a9..2afc9628 100644 --- a/app/src/main/assets/en/about_licenses_light.html +++ b/app/src/main/assets/en/about_licenses_light.html @@ -31,7 +31,7 @@

Privacy Browser is released under the GPLv3+ license. The full text of the license is below. The source code is available from git.stoutner.com.

-

Block Lists

+

Blocklists

EasyList and EasyPrivacy are dual licensed under the GPLv3+ and the Creative Commons Attribution-ShareAlike 3.0+ Unported licenses. @@ -44,8 +44,9 @@

More information about the blocklists can be found on the EasyList website.

Libraries

-

Privacy Browser is built with the Android Support Library, - which is released under the Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

The free flavor of Privacy Browser is built with Firebase Ads, which is released under the Android Software Development Kit License.

diff --git a/app/src/main/assets/es/about_licenses_dark.html b/app/src/main/assets/es/about_licenses_dark.html index 1c36c979..f51a5b63 100644 --- a/app/src/main/assets/es/about_licenses_dark.html +++ b/app/src/main/assets/es/about_licenses_dark.html @@ -46,8 +46,9 @@

Más información sobre las listas de bloqueo puede encontrarse en la página web de EasyList.

Librerías

-

Navegador privado está construido con la librería de soporte de android, - que se libera bajo la Licencia Apache 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

El sabor o versión libre de Navegador Privado está construido con anuncios de Firebase, que se libera bajo la Licencia del Android Software Development Kit.

diff --git a/app/src/main/assets/es/about_licenses_light.html b/app/src/main/assets/es/about_licenses_light.html index 1c8476f2..65fffafb 100644 --- a/app/src/main/assets/es/about_licenses_light.html +++ b/app/src/main/assets/es/about_licenses_light.html @@ -46,8 +46,9 @@

Más información sobre las listas de bloqueo puede encontrarse en la página web de EasyList.

Librerías

-

Navegador privado está construido con la librería de soporte de android, - que se libera bajo la Licencia Apache 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

El sabor o versión libre de Navegador Privado está construido con anuncios de Firebase, que se libera bajo la Licencia del Android Software Development Kit.

diff --git a/app/src/main/assets/it/about_licenses_dark.html b/app/src/main/assets/it/about_licenses_dark.html index 695c33dd..92643e3b 100644 --- a/app/src/main/assets/it/about_licenses_dark.html +++ b/app/src/main/assets/it/about_licenses_dark.html @@ -37,7 +37,7 @@ E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini qui riportati. Il codice sorgente è disponibile su git.stoutner.com.

-

Block List

+

Blocklist

EasyList e EasyPrivacy sono sotto doppia licenza con le licenze GPLv3+ e Creative Commons Attribution-ShareAlike 3.0+ Unported. Privacy Browser le incorpora utilizzando l'opzione GPLv3+.

@@ -49,8 +49,9 @@

E' possibile reperire maggiori informazioni sulle block list sul sito web EasyList.

Librerie

-

Privacy Browser è sviluppato con la Android Support Library, - che è rilasciata con Licenza Apache 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

La versione gratuita di Privacy Browser è compilata con Firebase Ads, che è rilasciato sotto la Licenza Android Software Development Kit.

diff --git a/app/src/main/assets/it/about_licenses_light.html b/app/src/main/assets/it/about_licenses_light.html index f8698477..23b33f40 100644 --- a/app/src/main/assets/it/about_licenses_light.html +++ b/app/src/main/assets/it/about_licenses_light.html @@ -37,7 +37,7 @@ E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini qui riportati. Il codice sorgente è disponibile su git.stoutner.com.

-

Block List

+

Blocklist

EasyList e EasyPrivacy sono sotto doppia licenza con le licenze GPLv3+ e Creative Commons Attribution-ShareAlike 3.0+ Unported. Privacy Browser le incorpora utilizzando l'opzione GPLv3+.

@@ -49,8 +49,9 @@

E' possibile reperire maggiori informazioni sulle block list sul sito web EasyList.

Librerie

-

Privacy Browser è sviluppato con la Android Support Library, - che è rilasciata con Licenza Apache 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

La versione gratuita di Privacy Browser è compilata con Firebase Ads, che è rilasciato sotto la Licenza Android Software Development Kit.

diff --git a/app/src/main/assets/ru/about_licenses_dark.html b/app/src/main/assets/ru/about_licenses_dark.html index fb207f62..4ff48e6b 100644 --- a/app/src/main/assets/ru/about_licenses_dark.html +++ b/app/src/main/assets/ru/about_licenses_dark.html @@ -44,8 +44,9 @@

Более подробную информацию о списках блокировки можно найти на веб-сайте EasyList.

Библиотеки

-

Privacy Browser создан с использованием Android Support Library, - которая выпущена под Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

Бесплатный вариант Privacy Browser создан с помощью Firebase Ads, выпущенной по лицензии Android Software Development Kit License.

diff --git a/app/src/main/assets/ru/about_licenses_light.html b/app/src/main/assets/ru/about_licenses_light.html index 9770ee6d..eb8a9c0a 100644 --- a/app/src/main/assets/ru/about_licenses_light.html +++ b/app/src/main/assets/ru/about_licenses_light.html @@ -44,8 +44,9 @@

Более подробную информацию о списках блокировки можно найти на веб-сайте EasyList.

Библиотеки

-

Privacy Browser создан с использованием Android Support Library, - которая выпущена под Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

Бесплатный вариант Privacy Browser создан с помощью Firebase Ads, выпущенной по лицензии Android Software Development Kit License.

diff --git a/app/src/main/assets/tr/about_licenses_dark.html b/app/src/main/assets/tr/about_licenses_dark.html index da0defc4..98308dd4 100644 --- a/app/src/main/assets/tr/about_licenses_dark.html +++ b/app/src/main/assets/tr/about_licenses_dark.html @@ -44,8 +44,9 @@

More information about the blocklists can be found on the EasyList website.

Libraries

-

Privacy Browser is built with the Android Support Library, - which is released under the Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

The free flavor of Privacy Browser is built with Firebase Ads, which is released under the Android Software Development Kit License.

diff --git a/app/src/main/assets/tr/about_licenses_light.html b/app/src/main/assets/tr/about_licenses_light.html index 5ecac0a9..7aa77d4b 100644 --- a/app/src/main/assets/tr/about_licenses_light.html +++ b/app/src/main/assets/tr/about_licenses_light.html @@ -44,8 +44,9 @@

More information about the blocklists can be found on the EasyList website.

Libraries

-

Privacy Browser is built with the Android Support Library, - which is released under the Apache License 2.0.

+

Privacy Browser is built with the AndroidX Libraries + and code from the Google Material Maven repository, + which are released under the Apache License 2.0.

The free flavor of Privacy Browser is built with Firebase Ads, which is released under the Android Software Development Kit License.

diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java index ca71d59c..d84b9c49 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -20,16 +20,18 @@ package com.stoutner.privacybrowser.activities; import android.os.Bundle; -import android.support.design.widget.TabLayout; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; import android.view.WindowManager; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.tabs.TabLayout; + import com.stoutner.privacybrowser.fragments.AboutTabFragment; import com.stoutner.privacybrowser.R; @@ -55,13 +57,17 @@ public class AboutActivity extends AppCompatActivity { setContentView(R.layout.about_coordinatorlayout); // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21. - Toolbar aboutAppBar = findViewById(R.id.about_toolbar); - setSupportActionBar(aboutAppBar); + Toolbar toolbar = findViewById(R.id.about_toolbar); + setSupportActionBar(toolbar); + + // Get a handle for the action bar. + final ActionBar actionBar = getSupportActionBar(); + + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; // - // Display the home arrow on `supportAppBar`. - final ActionBar appBar = getSupportActionBar(); - assert appBar != null; // This assert removes the incorrect warning in Android Studio on the following line that appBar might be null. - appBar.setDisplayHomeAsUpEnabled(true); + // Display the home arrow on action bar. + actionBar.setDisplayHomeAsUpEnabled(true); // Setup the ViewPager. ViewPager aboutViewPager = findViewById(R.id.about_viewpager); @@ -73,8 +79,9 @@ public class AboutActivity extends AppCompatActivity { } private class aboutPagerAdapter extends FragmentPagerAdapter { - private aboutPagerAdapter(FragmentManager fm) { - super(fm); + private aboutPagerAdapter(FragmentManager fragmentManager) { + // Run the default commands. + super(fragmentManager); } @Override diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java index 38584187..b93dc363 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java @@ -19,6 +19,7 @@ package com.stoutner.privacybrowser.activities; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -29,14 +30,6 @@ import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; -import android.support.v4.app.NavUtils; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; -import android.support.v7.widget.Toolbar; import android.util.SparseBooleanArray; import android.view.ActionMode; import android.view.Menu; @@ -52,6 +45,15 @@ import android.widget.ListView; import android.widget.RadioButton; import android.widget.TextView; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API is >= 21. +import androidx.core.app.NavUtils; +import androidx.fragment.app.DialogFragment; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog; import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog; import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog; @@ -144,9 +146,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Set the content view. setContentView(R.layout.bookmarks_coordinatorlayout); - // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. - final Toolbar bookmarksAppBar = findViewById(R.id.bookmarks_toolbar); - setSupportActionBar(bookmarksAppBar); + // The AndroidX toolbar must be used until the minimum API is >= 21. + final Toolbar toolbar = findViewById(R.id.bookmarks_toolbar); + setSupportActionBar(toolbar); // Get a handle for the activity, the app bar, and the ListView. final Activity bookmarksActivity = this; @@ -395,7 +397,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma checkedItemIds = bookmarksListView.getCheckedItemIds(); // Show the `MoveToFolderDialog` `AlertDialog` and name the instance `@string/move_to_folder - AppCompatDialogFragment moveToFolderDialog = new MoveToFolderDialog(); + DialogFragment moveToFolderDialog = new MoveToFolderDialog(); moveToFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.move_to_folder)); break; @@ -419,11 +421,11 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME)); // Show the edit bookmark folder dialog. - AppCompatDialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId); + DialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId); editFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_folder)); } else { // Show the edit bookmark dialog. - AppCompatDialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId); + DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId); editBookmarkDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark)); } break; @@ -451,6 +453,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { + @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`. @Override public void onDismissed(Snackbar snackbar, int event) { switch (event) { @@ -544,14 +547,14 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Set the create new bookmark folder FAB to display the `AlertDialog`. createBookmarkFolderFab.setOnClickListener(v -> { // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`. - AppCompatDialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog(); + DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog(); createBookmarkFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_folder)); }); // Set the create new bookmark FAB to display the `AlertDialog`. createBookmarkFab.setOnClickListener(view -> { // Show the `CreateBookmarkDialog` `AlertDialog` and name the instance `@string/create_bookmark`. - AppCompatDialogFragment createBookmarkDialog = new CreateBookmarkDialog(); + DialogFragment createBookmarkDialog = new CreateBookmarkDialog(); createBookmarkDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_bookmark)); }); } @@ -637,7 +640,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } @Override - public void onCreateBookmark(AppCompatDialogFragment dialogFragment) { + public void onCreateBookmark(DialogFragment dialogFragment) { // Get the `EditTexts` from the `dialogFragment`. EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext); EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext); @@ -668,7 +671,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } @Override - public void onCreateBookmarkFolder(AppCompatDialogFragment dialogFragment) { + public void onCreateBookmarkFolder(DialogFragment dialogFragment) { // Get handles for the views in `dialogFragment`. EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext); RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton); @@ -713,7 +716,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } @Override - public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) { + public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) { // Get handles for the views from `dialogFragment`. EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext); EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext); @@ -747,7 +750,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } @Override - public void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId) { + public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) { // Get handles for the views from `dialogFragment`. RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton); RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton); @@ -814,7 +817,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } @Override - public void onMoveToFolder(AppCompatDialogFragment dialogFragment) { + public void onMoveToFolder(DialogFragment dialogFragment) { // Get a handle for the `ListView` from `dialogFragment`. ListView folderListView = dialogFragment.getDialog().findViewById(R.id.move_to_folder_listview); diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java index 70bd7735..4bdbd44c 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java @@ -19,6 +19,7 @@ package com.stoutner.privacybrowser.activities; +import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; import android.database.MatrixCursor; @@ -29,15 +30,6 @@ import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.design.widget.Snackbar; -import android.support.v4.content.ContextCompat; -import android.support.v4.widget.CursorAdapter; -import android.support.v4.widget.ResourceCursorAdapter; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; -import android.support.v7.widget.Toolbar; import android.util.SparseBooleanArray; import android.view.ActionMode; import android.view.Menu; @@ -51,9 +43,19 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.RadioButton; +import android.widget.ResourceCursorAdapter; import android.widget.Spinner; import android.widget.TextView; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API is >= 21. +import androidx.core.content.ContextCompat; +import androidx.cursoradapter.widget.CursorAdapter; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + +import com.google.android.material.snackbar.Snackbar; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.EditBookmarkDatabaseViewDialog; import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDatabaseViewDialog; @@ -115,19 +117,19 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements // Set the content view. setContentView(R.layout.bookmarks_databaseview_coordinatorlayout); - // The `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21. - Toolbar bookmarksDatabaseViewAppBar = findViewById(R.id.bookmarks_databaseview_toolbar); - setSupportActionBar(bookmarksDatabaseViewAppBar); + // The AndroidX toolbar must be used until the minimum API is >= 21. + Toolbar toolbar = findViewById(R.id.bookmarks_databaseview_toolbar); + setSupportActionBar(toolbar); // Get a handle for the `AppBar`. - ActionBar appBar = getSupportActionBar(); + ActionBar actionBar = getSupportActionBar(); - // Remove the incorrect warning in Android Studio that `appBar` might be null. - assert appBar != null; + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; - // Display the spinner and the back arrow in the app bar. - appBar.setCustomView(R.layout.spinner); - appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP); + // Display the spinner and the back arrow in the action bar. + actionBar.setCustomView(R.layout.spinner); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP); // Initialize the database handler. The `0` is to specify a database version, but that is set instead using a constant in `BookmarksDatabaseHelper`. bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0); @@ -335,11 +337,11 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME)); // Show the edit bookmark folder dialog. - AppCompatDialogFragment editBookmarkFolderDatabaseViewDialog = EditBookmarkFolderDatabaseViewDialog.folderDatabaseId(databaseId); + DialogFragment editBookmarkFolderDatabaseViewDialog = EditBookmarkFolderDatabaseViewDialog.folderDatabaseId(databaseId); editBookmarkFolderDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_folder)); } else { // Show the edit bookmark dialog. - AppCompatDialogFragment editBookmarkDatabaseViewDialog = EditBookmarkDatabaseViewDialog.bookmarkDatabaseId(databaseId); + DialogFragment editBookmarkDatabaseViewDialog = EditBookmarkDatabaseViewDialog.bookmarkDatabaseId(databaseId); editBookmarkDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark)); } }); @@ -502,6 +504,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { + @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`. @Override public void onDismissed(Snackbar snackbar, int event) { switch (event) { @@ -733,7 +736,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements } @Override - public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) { + public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) { // Get handles for the views from dialog fragment. RadioButton currentBookmarkIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_current_icon_radiobutton); EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext); @@ -775,7 +778,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements } @Override - public void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) { + public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) { // Get handles for the views from dialog fragment. RadioButton currentBookmarkIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton); RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton); diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java index 7dbb6bf3..d54499a2 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java @@ -19,6 +19,7 @@ package com.stoutner.privacybrowser.activities; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -27,15 +28,6 @@ import android.database.Cursor; import android.net.http.SslCertificate; import android.os.Bundle; import android.os.Handler; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.NavUtils; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; -import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -49,6 +41,16 @@ import android.widget.Spinner; import android.widget.Switch; import android.widget.TextView; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API is >= 21. +import androidx.core.app.NavUtils; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.AddDomainDialog; import com.stoutner.privacybrowser.fragments.DomainSettingsFragment; @@ -79,9 +81,6 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // `context` is used in `onCreate()`, `onOptionsItemSelected()`, and `onAddDomain()`. private Context context; - // `supportFragmentManager` is used in `onCreate()` and `onCreateOptionsMenu()`. - private FragmentManager supportFragmentManager; - // `domainsDatabaseHelper` is used in `onCreate()`, `saveDomainSettings()`, and `onDestroy()`. private static DomainsDatabaseHelper domainsDatabaseHelper; @@ -155,16 +154,19 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo coordinatorLayout = findViewById(R.id.domains_coordinatorlayout); resources = getResources(); context = this; - supportFragmentManager = getSupportFragmentManager(); // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21. - final Toolbar domainsAppBar = findViewById(R.id.domains_toolbar); - setSupportActionBar(domainsAppBar); + final Toolbar toolbar = findViewById(R.id.domains_toolbar); + setSupportActionBar(toolbar); + + // Get a handle for the action bar. + ActionBar actionBar = getSupportActionBar(); - // Display the home arrow on the support action bar. - ActionBar appBar = getSupportActionBar(); - assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that `appBar` might be null. - appBar.setDisplayHomeAsUpEnabled(true); + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; + + // Set the back arrow on the action bar. + actionBar.setDisplayHomeAsUpEnabled(true); // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. domainsDatabaseHelper = new DomainsDatabaseHelper(context, null, null, 0); @@ -176,8 +178,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo addDomainFAB = findViewById(R.id.add_domain_fab); addDomainFAB.setOnClickListener((View view) -> { // Show the add domain `AlertDialog`. - AppCompatDialogFragment addDomainDialog = new AddDomainDialog(); - addDomainDialog.show(supportFragmentManager, resources.getString(R.string.add_domain)); + DialogFragment addDomainDialog = new AddDomainDialog(); + addDomainDialog.show(getSupportFragmentManager(), resources.getString(R.string.add_domain)); }); } @@ -192,6 +194,9 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Only display `deleteMenuItem` (initially) in two-paned mode. deleteMenuItem.setVisible(twoPanedMode); + // Get a handle for the fragment manager. + FragmentManager fragmentManager = getSupportFragmentManager(); + // Display the fragments. This must be done from `onCreateOptionsMenu()` instead of `onCreate()` because `populateDomainsListView()` needs `deleteMenuItem` to be inflated. if (restartAfterRotate && domainSettingsDisplayedBeforeRotate) { // The device was rotated and domain settings were displayed previously. if (twoPanedMode) { // The device is in two-paned mode. @@ -200,8 +205,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Display `DomainsListFragment`. DomainsListFragment domainsListFragment = new DomainsListFragment(); - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); - supportFragmentManager.executePendingTransactions(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); + fragmentManager.executePendingTransactions(); // Populate the list of domains. `domainSettingsDatabaseId` highlights the domain that was highlighted before the rotation. populateDomainsListView(domainSettingsDatabaseIdBeforeRotate); @@ -227,7 +232,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo addDomainFAB.hide(); // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); } } else { // The device was not rotated or, if it was, domain settings were not displayed previously. if (goDirectlyToDatabaseId >=0) { // Load the indicated domain settings. @@ -237,8 +242,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo if (twoPanedMode) { // The device is in two-paned mode. // Display `DomainsListFragment`. DomainsListFragment domainsListFragment = new DomainsListFragment(); - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); - supportFragmentManager.executePendingTransactions(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); + fragmentManager.executePendingTransactions(); // Populate the list of domains. `domainSettingsDatabaseId` highlights the domain that was highlighted before the rotation. populateDomainsListView(goDirectlyToDatabaseId); @@ -258,13 +263,13 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo addDomainFAB.hide(); // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); } } else { // Highlight the first domain. // Display `DomainsListFragment`. DomainsListFragment domainsListFragment = new DomainsListFragment(); - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); - supportFragmentManager.executePendingTransactions(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); + fragmentManager.executePendingTransactions(); // Populate the list of domains. `-1` highlights the first domain. populateDomainsListView(-1); @@ -277,9 +282,12 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo @Override public boolean onOptionsItemSelected(MenuItem menuItem) { - // Get the ID of the `MenuItem` that was selected. + // Get the ID of the menu item that was selected. int menuItemID = menuItem.getItemId(); + // Get a handle for the fragment manager. + FragmentManager fragmentManager = getSupportFragmentManager(); + switch (menuItemID) { case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`. if (twoPanedMode) { // The device is in two-paned mode. @@ -311,8 +319,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Display the domains list fragment. DomainsListFragment domainsListFragment = new DomainsListFragment(); - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); - supportFragmentManager.executePendingTransactions(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); + fragmentManager.executePendingTransactions(); // Populate the list of domains. `-1` highlights the first domain if in two-paned mode. It has no effect in single-paned mode. populateDomainsListView(-1); @@ -354,12 +362,12 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo deleteMenuItem.setIcon(R.drawable.delete_blue); // Remove the domain settings fragment. - supportFragmentManager.beginTransaction().remove(Objects.requireNonNull(supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container))).commit(); + fragmentManager.beginTransaction().remove(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.domain_settings_fragment_container))).commit(); } else { // Single-paned mode. // Display `DomainsListFragment`. DomainsListFragment domainsListFragment = new DomainsListFragment(); - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); - supportFragmentManager.executePendingTransactions(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); + fragmentManager.executePendingTransactions(); // Show the add domain FAB. addDomainFAB.show(); @@ -403,6 +411,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { + @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`. @Override public void onDismissed(Snackbar snackbar, int event) { switch (event) { @@ -444,14 +453,14 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo domainsListView.setItemChecked(deletedDomainPosition, true); // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit(); + fragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit(); // Enable the options `MenuItems`. deleteMenuItem.setEnabled(true); deleteMenuItem.setIcon(R.drawable.delete_light); } else { // The device in in one-paned mode. // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); // Hide the add domain FAB. addDomainFAB.hide(); @@ -460,7 +469,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo deleteMenuItem.setVisible(true); // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); } break; @@ -539,6 +548,9 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Control what the navigation bar back button does. @Override public void onBackPressed() { + // Get a handle for the fragment manager. + FragmentManager fragmentManager = getSupportFragmentManager(); + if (twoPanedMode) { // The device is in two-paned mode. // Save the current domain settings if the domain settings fragment is displayed. if (findViewById(R.id.domain_settings_scrollview) != null) { @@ -568,8 +580,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Display the domains list fragment. DomainsListFragment domainsListFragment = new DomainsListFragment(); - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); - supportFragmentManager.executePendingTransactions(); + fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit(); + fragmentManager.executePendingTransactions(); // Populate the list of domains. `-1` highlights the first domain if in two-paned mode. It has no effect in single-paned mode. populateDomainsListView(-1); @@ -595,7 +607,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo } @Override - public void onAddDomain(AppCompatDialogFragment dialogFragment) { + public void onAddDomain(DialogFragment dialogFragment) { // Dismiss the undo delete snackbar if it is currently displayed. if ((undoDeleteSnackbar != null) && undoDeleteSnackbar.isShown()) { undoDeleteSnackbar.dismiss(); @@ -618,16 +630,16 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Show and enable `deleteMenuItem`. DomainsActivity.deleteMenuItem.setVisible(true); - // Add `currentDomainDatabaseId` to `argumentsBundle`. + // Add the current domain database ID to the arguments bundle. Bundle argumentsBundle = new Bundle(); argumentsBundle.putInt(DomainSettingsFragment.DATABASE_ID, currentDomainDatabaseId); - // Add `argumentsBundle` to `domainSettingsFragment`. + // Add and arguments bundle to the domain setting fragment. DomainSettingsFragment domainSettingsFragment = new DomainSettingsFragment(); domainSettingsFragment.setArguments(argumentsBundle); - // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); + // Display the domain settings fragment. + getSupportFragmentManager().beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); } } @@ -788,22 +800,22 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Select the highlighted domain. domainsListView.setItemChecked(highlightedDomainPosition, true); - // Get the `databaseId` for the highlighted domain. + // Get the database ID for the highlighted domain. domainsCursor.moveToPosition(highlightedDomainPosition); currentDomainDatabaseId = domainsCursor.getInt(domainsCursor.getColumnIndex(DomainsDatabaseHelper._ID)); - // Store `databaseId` in `argumentsBundle`. + // Store the database ID in the arguments bundle. Bundle argumentsBundle = new Bundle(); argumentsBundle.putInt(DomainSettingsFragment.DATABASE_ID, currentDomainDatabaseId); - // Add `argumentsBundle` to `domainSettingsFragment`. + // Add and arguments bundle to the domain settings fragment. DomainSettingsFragment domainSettingsFragment = new DomainSettingsFragment(); domainSettingsFragment.setArguments(argumentsBundle); - // Display `domainSettingsFragment`. - supportFragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit(); + // Display the domain settings fragment. + getSupportFragmentManager().beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit(); - // Enable the options `MenuItems`. + // Enable the delete options menu items. deleteMenuItem.setEnabled(true); // Set the delete icon according to the theme. diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/GuideActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/GuideActivity.java index 5cbf0c50..0f73f065 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/GuideActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/GuideActivity.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -20,16 +20,18 @@ package com.stoutner.privacybrowser.activities; import android.os.Bundle; -import android.support.design.widget.TabLayout; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; import android.view.WindowManager; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API is >= 21. +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.tabs.TabLayout; + import com.stoutner.privacybrowser.fragments.GuideTabFragment; import com.stoutner.privacybrowser.R; @@ -54,14 +56,18 @@ public class GuideActivity extends AppCompatActivity { // Set the content view. setContentView(R.layout.guide_coordinatorlayout); - // We need to use `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. - Toolbar guideAppBar = findViewById(R.id.guide_toolbar); - setSupportActionBar(guideAppBar); + // The AndroidX toolbar must be used until the minimum API is >= 21. + Toolbar toolbar = findViewById(R.id.guide_toolbar); + setSupportActionBar(toolbar); + + // Get a handle for the action bar. + final ActionBar actionBar = getSupportActionBar(); + + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; - // Display the home arrow on `ppBar`. - final ActionBar appBar = getSupportActionBar(); - assert appBar != null; // This assert removes the incorrect lint warning in Android Studio on the following line that `appBar` might be `null`. - appBar.setDisplayHomeAsUpEnabled(true); + // Display the home arrow on the action bar. + actionBar.setDisplayHomeAsUpEnabled(true); // Setup the ViewPager. ViewPager aboutViewPager = findViewById(R.id.guide_viewpager); @@ -75,8 +81,9 @@ public class GuideActivity extends AppCompatActivity { } private class guidePagerAdapter extends FragmentPagerAdapter { - private guidePagerAdapter(FragmentManager fm) { - super(fm); + private guidePagerAdapter(FragmentManager fragmentManager) { + // Run the default commands. + super(fragmentManager); } @Override diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java index 80a3a98f..3f7d2962 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java @@ -29,17 +29,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.DocumentsContract; -import android.support.annotation.NonNull; -import android.support.design.widget.Snackbar; -import android.support.design.widget.TextInputLayout; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.DialogFragment; -import android.support.v4.content.ContextCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.CardView; -import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; import android.view.View; @@ -53,6 +42,19 @@ import android.widget.RadioButton; import android.widget.Spinner; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.cardview.widget.CardView; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.fragment.app.DialogFragment; + +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.textfield.TextInputLayout; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog; import com.stoutner.privacybrowser.helpers.ImportExportDatabaseHelper; @@ -105,13 +107,17 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe setContentView(R.layout.import_export_coordinatorlayout); // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. - Toolbar importExportAppBar = findViewById(R.id.import_export_toolbar); - setSupportActionBar(importExportAppBar); + Toolbar toolbar = findViewById(R.id.import_export_toolbar); + setSupportActionBar(toolbar); + + // Get a handle for the action bar. + ActionBar actionBar = getSupportActionBar(); + + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; // Display the home arrow on the support action bar. - ActionBar appBar = getSupportActionBar(); - assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that `appBar` might be null. - appBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(true); // Find out if we are running KitKat boolean runningKitKat = (Build.VERSION.SDK_INT == 19); @@ -162,11 +168,11 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe // Set the default file paths according to the storage permission status. if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. // Set the default file paths to use the external public directory. - defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.privacy_browser_settings_pbs); + defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.settings_pbs); defaultPasswordEncryptionFilePath = defaultFilePath + ".aes"; } else { // The storage permission has not been granted. // Set the default file paths to use the external private directory. - defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.privacy_browser_settings_pbs); + defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.settings_pbs); defaultPasswordEncryptionFilePath = defaultFilePath + ".aes"; } @@ -438,7 +444,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe exportBrowseIntent.setType("*/*"); // Set the initial export file name. - exportBrowseIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.privacy_browser_settings_pbs)); + exportBrowseIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.settings_pbs)); // Set the initial directory if the minimum API >= 26. if (Build.VERSION.SDK_INT >= 26) { @@ -599,7 +605,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe case OPENPGP_EXPORT_RESULT_CODE: // Get the temporary unencrypted export file. - File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs)); + File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs)); // Delete the temporary unencrypted export file if it exists. if (temporaryUnencryptedExportFile.exists()) { @@ -623,7 +629,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe // Get the export and temporary unencrypted export files. File exportFile = new File(exportFileString); - File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs)); + File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs)); // Create an export status string. String exportStatus; @@ -802,7 +808,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe case PASSWORD_ENCRYPTION: // Use a private temporary import location. - File temporaryUnencryptedImportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs)); + File temporaryUnencryptedImportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs)); try { // Create an encrypted import file input stream. diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/LogcatActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/LogcatActivity.java index 32d1bf47..a615a541 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/LogcatActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/LogcatActivity.java @@ -31,22 +31,22 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.design.widget.Snackbar; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.DialogFragment; -import android.support.v4.content.ContextCompat; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.app.AppCompatDialogFragment; -import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.WindowManager; import android.widget.EditText; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API is >= 21. +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.google.android.material.snackbar.Snackbar; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog; import com.stoutner.privacybrowser.dialogs.SaveLogcatDialog; @@ -86,18 +86,18 @@ public class LogcatActivity extends AppCompatActivity implements SaveLogcatDialo // Set the content view. setContentView(R.layout.logcat_coordinatorlayout); - // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. - Toolbar logcatAppBar = findViewById(R.id.logcat_toolbar); - setSupportActionBar(logcatAppBar); + // The AndroidX toolbar must be used until the minimum API is >= 21. + Toolbar toolbar = findViewById(R.id.logcat_toolbar); + setSupportActionBar(toolbar); - // Get a handle for the app bar. - ActionBar appBar = getSupportActionBar(); + // Get a handle for the action bar. + ActionBar actionBar = getSupportActionBar(); - // Remove the incorrect lint warning that `appBar` might be null. - assert appBar != null; + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; - // Display the the back arrow in the app bar. - appBar.setDisplayHomeAsUpEnabled(true); + // Display the the back arrow in the action bar. + actionBar.setDisplayHomeAsUpEnabled(true); // Implement swipe to refresh. SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.logcat_swiperefreshlayout); @@ -190,7 +190,7 @@ public class LogcatActivity extends AppCompatActivity implements SaveLogcatDialo } @Override - public void onSaveLogcat(AppCompatDialogFragment dialogFragment) { + public void onSaveLogcat(DialogFragment dialogFragment) { // Get a handle for the file name edit text. EditText fileNameEditText = dialogFragment.getDialog().findViewById(R.id.file_name_edittext); diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 868b6d71..bbdf8530 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -24,7 +24,6 @@ package com.stoutner.privacybrowser.activities; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; -import android.app.DialogFragment; import android.app.DownloadManager; import android.app.SearchManager; import android.content.ActivityNotFoundException; @@ -55,26 +54,6 @@ import android.os.Handler; import android.preference.PreferenceManager; import android.print.PrintDocumentAdapter; import android.print.PrintManager; -import android.support.annotation.NonNull; -import android.support.design.widget.CoordinatorLayout; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.NavigationView; -import android.support.design.widget.Snackbar; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.FragmentManager; -import android.support.v4.content.ContextCompat; -// `ShortcutInfoCompat`, `ShortcutManagerCompat`, and `IconCompat` can be switched to the non-compat version once API >= 26. -import android.support.v4.content.pm.ShortcutInfoCompat; -import android.support.v4.content.pm.ShortcutManagerCompat; -import android.support.v4.graphics.drawable.IconCompat; -import android.support.v4.view.GravityCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarDrawerToggle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.app.AppCompatDialogFragment; -import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.Spanned; import android.text.TextWatcher; @@ -114,6 +93,28 @@ import android.widget.RadioButton; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +// `ShortcutInfoCompat`, `ShortcutManagerCompat`, and `IconCompat` can be switched to the non-compat versions once API >= 26. +import androidx.core.content.pm.ShortcutInfoCompat; +import androidx.core.content.pm.ShortcutManagerCompat; +import androidx.core.graphics.drawable.IconCompat; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.navigation.NavigationView; +import com.google.android.material.snackbar.Snackbar; + import com.stoutner.privacybrowser.BuildConfig; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.AdConsentDialog; @@ -308,23 +309,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `ignorePinnedDomainInformation` is used in `onSslMismatchProceed()`, `applyDomainSettings()`, and `checkPinnedMismatch()`. private static boolean ignorePinnedDomainInformation; - // `supportFragmentManager` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onCreateContextMenu()`, `onRequestPermissionResult()`, `viewSslCertificate()`, - // `applyAppSettings()`, and `checkPinnedMismatch()`. - private static FragmentManager supportFragmentManager; - + // The fragment manager is initialized in `onCreate()` and accessed from the static `checkPinnedMismatch()`. + private static FragmentManager fragmentManager; - // `appBar` is used in `onCreate()`, `onOptionsItemSelected()`, `closeFindOnPage()`, `applyAppSettings()`, and `applyProxyThroughOrbot()`. - private ActionBar appBar; // `navigatingHistory` is used in `onCreate()`, `onNavigationItemSelected()`, `onSslMismatchBack()`, and `applyDomainSettings()`. private boolean navigatingHistory; - // `drawerLayout` is used in `onCreate()`, `onNewIntent()`, `onBackPressed()`, and `onRestart()`. - private DrawerLayout drawerLayout; - - // `rootCoordinatorLayout` is used in `onCreate()` and `applyAppSettings()`. - private CoordinatorLayout rootCoordinatorLayout; - // `mainWebView` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`, // `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, and `applyProxyThroughOrbot()`. private WebView mainWebView; @@ -332,9 +323,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`. private FrameLayout fullScreenVideoFrameLayout; - // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `onRestart()`. - private SwipeRefreshLayout swipeRefreshLayout; - // `urlAppBarRelativeLayout` is used in `onCreate()` and `applyDomainSettings()`. private RelativeLayout urlAppBarRelativeLayout; @@ -462,11 +450,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `displayAdditionalAppBarIcons` is used in `onCreate()` and `onCreateOptionsMenu()`. private boolean displayAdditionalAppBarIcons; - // `drawerToggle` is used in `onCreate()`, `onPostCreate()`, `onConfigurationChanged()`, `onNewIntent()`, and `onNavigationItemSelected()`. - private ActionBarDrawerToggle drawerToggle; - - // `supportAppBar` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. - private Toolbar supportAppBar; + // The action bar drawer toggle is initialized in `onCreate()` and used in `onPostCreate()`. + private ActionBarDrawerToggle actionBarDrawerToggle; // `urlTextBox` is used in `onCreate()`, `onOptionsItemSelected()`, `loadUrlFromTextBox()`, `loadUrl()`, and `highlightUrlText()`. private EditText urlTextBox; @@ -490,9 +475,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `inputMethodManager` is used in `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `closeFindOnPage()`. private InputMethodManager inputMethodManager; - // `mainWebViewRelativeLayout` is used in `onCreate()` and `onNavigationItemSelected()`. - private RelativeLayout mainWebViewRelativeLayout; - // `bookmarksDatabaseHelper` is used in `onCreate()`, `onDestroy`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, // and `loadBookmarksFolder()`. private BookmarksDatabaseHelper bookmarksDatabaseHelper; @@ -563,24 +545,22 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the content view. setContentView(R.layout.main_drawerlayout); - // Get a handle for the resources and the support fragment manager. + // Get handles for views, resources, and managers. Resources resources = getResources(); - supportFragmentManager = getSupportFragmentManager(); - - // Get a handle for `inputMethodManager`. + fragmentManager = getSupportFragmentManager(); inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + Toolbar toolbar = findViewById(R.id.toolbar); - // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21. - supportAppBar = findViewById(R.id.app_bar); - setSupportActionBar(supportAppBar); - appBar = getSupportActionBar(); + // Set the action bar. `SupportActionBar` must be used until the minimum API is >= 21. + setSupportActionBar(toolbar); + ActionBar actionBar = getSupportActionBar(); - // This is needed to get rid of the Android Studio warning that `appBar` might be null. - assert appBar != null; + // This is needed to get rid of the Android Studio warning that the action bar might be null. + assert actionBar != null; // Add the custom `url_app_bar` layout, which shows the favorite icon and the URL text bar. - appBar.setCustomView(R.layout.url_app_bar); - appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); + actionBar.setCustomView(R.layout.url_app_bar); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); // Initialize the foreground color spans for highlighting the URLs. We have to use the deprecated `getColor()` until API >= 23. redColorSpan = new ForegroundColorSpan(resources.getColor(R.color.red_a700)); @@ -650,15 +630,15 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Register `orbotStatusBroadcastReceiver` on `this` context. this.registerReceiver(orbotStatusBroadcastReceiver, new IntentFilter("org.torproject.android.intent.action.STATUS")); - // Get handles for views that need to be accessed. - drawerLayout = findViewById(R.id.drawerlayout); - rootCoordinatorLayout = findViewById(R.id.root_coordinatorlayout); + // Get handles for views that need to be modified. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorlayout); bookmarksListView = findViewById(R.id.bookmarks_drawer_listview); bookmarksTitleTextView = findViewById(R.id.bookmarks_title_textview); FloatingActionButton launchBookmarksActivityFab = findViewById(R.id.launch_bookmarks_activity_fab); FloatingActionButton createBookmarkFolderFab = findViewById(R.id.create_bookmark_folder_fab); FloatingActionButton createBookmarkFab = findViewById(R.id.create_bookmark_fab); - mainWebViewRelativeLayout = findViewById(R.id.main_webview_relativelayout); + SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); mainWebView = findViewById(R.id.main_webview); findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout); findOnPageEditText = findViewById(R.id.find_on_page_edittext); @@ -693,16 +673,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the create new bookmark folder FAB to display an alert dialog. createBookmarkFolderFab.setOnClickListener(v -> { - // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`. - AppCompatDialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog(); - createBookmarkFolderDialog.show(supportFragmentManager, resources.getString(R.string.create_folder)); + // Show the create bookmark folder dialog and name the instance `@string/create_folder`. + DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog(); + createBookmarkFolderDialog.show(fragmentManager, resources.getString(R.string.create_folder)); }); // Set the create new bookmark FAB to display an alert dialog. createBookmarkFab.setOnClickListener(view -> { - // Show the `CreateBookmarkDialog` `AlertDialog` and name the instance `@string/create_bookmark`. - AppCompatDialogFragment createBookmarkDialog = new CreateBookmarkDialog(); - createBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.create_bookmark)); + // Show the create bookmark dialog and name the instance `@string/create_bookmark`. + DialogFragment createBookmarkDialog = new CreateBookmarkDialog(); + createBookmarkDialog.show(fragmentManager, resources.getString(R.string.create_bookmark)); }); // Create a double-tap listener to toggle full-screen mode. @@ -715,8 +695,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook inFullScreenBrowsingMode = !inFullScreenBrowsingMode; if (inFullScreenBrowsingMode) { // Switch to full screen mode. - // Hide the `appBar`. - appBar.hide(); + // Hide the action bar. + actionBar.hide(); // Hide the banner ad in the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { @@ -736,13 +716,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown. */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - // Set `rootCoordinatorLayout` to fill the whole screen. - rootCoordinatorLayout.setFitsSystemWindows(false); + // Set the coordinator layout to fill the entire screen. + coordinatorLayout.setFitsSystemWindows(false); } else { // Hide everything except the status and navigation bars. - // Set `rootCoordinatorLayout` to fit under the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(false); + // Set the coordinator layout to fill the entire screen. + coordinatorLayout.setFitsSystemWindows(false); // There is an Android Support Library bug that causes a scrim to print on the right side of the `Drawer Layout` when the navigation bar is displayed on the right of the screen. if (translucentNavigationBarOnFullscreen) { @@ -751,8 +731,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } } else { // Switch to normal viewing mode. - // Show the `appBar`. - appBar.show(); + // Show the action bar. + actionBar.show(); // Show the `BannerAd` in the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { @@ -766,11 +746,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); + // Remove any `SYSTEM_UI` flags from the coordinator layout. + coordinatorLayout.setSystemUiVisibility(0); - // Constrain `rootCoordinatorLayout` inside the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(true); + // Constrain the coordinator layout inside the status and navigation bars. + coordinatorLayout.setFitsSystemWindows(true); } // Consume the double-tap. @@ -782,9 +762,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook }); // Pass all touch events on `mainWebView` through `gestureDetector` to check for double-taps. - mainWebView.setOnTouchListener((View v, MotionEvent event) -> { + mainWebView.setOnTouchListener((View view, MotionEvent event) -> { // Call `performClick()` on the view, which is required for accessibility. - v.performClick(); + view.performClick(); // Send the `event` to `gestureDetector`. return gestureDetector.onTouchEvent(event); @@ -847,7 +827,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook }); // Implement swipe to refresh. - swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); swipeRefreshLayout.setOnRefreshListener(() -> mainWebView.reload()); // Set the swipe to refresh color according to the theme. @@ -921,12 +900,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME)); // Show the edit bookmark folder `AlertDialog` and name the instance `@string/edit_folder`. - AppCompatDialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId); - editFolderDialog.show(supportFragmentManager, resources.getString(R.string.edit_folder)); + DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId); + editBookmarkFolderDialog.show(fragmentManager, resources.getString(R.string.edit_folder)); } else { // Show the edit bookmark `AlertDialog` and name the instance `@string/edit_bookmark`. - AppCompatDialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId); - editBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.edit_bookmark)); + DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId); + editBookmarkDialog.show(fragmentManager, resources.getString(R.string.edit_bookmark)); } // Consume the event. @@ -992,8 +971,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } }); - // drawerToggle creates the hamburger icon at the start of the AppBar. - drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, supportAppBar, R.string.open_navigation_drawer, R.string.close_navigation_drawer); + // Create the hamburger icon at the start of the AppBar. + actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer); // Get a handle for the progress bar. final ProgressBar progressBar = findViewById(R.id.progress_bar); @@ -1092,10 +1071,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown. */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + + // Set the coordinator layout to fill the entire screen. + coordinatorLayout.setFitsSystemWindows(false); - // Set `rootCoordinatorLayout` to fill the entire screen. - rootCoordinatorLayout.setFitsSystemWindows(false); + // Hide the action bar. + actionBar.hide(); // Disable the sliding drawers. drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); @@ -1134,10 +1116,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown. */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } else { // Hide everything except the status and navigation bars. - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); + // Remove any `SYSTEM_UI` flags from the coordinator layout. + coordinatorLayout.setSystemUiVisibility(0); // Add the translucent status flag if it is unset. getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); @@ -1151,19 +1133,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } } else { // Switch to normal viewing mode. - // Show the `appBar` if `findOnPageLinearLayout` is not visible. + // Show the action bar if the find on page linear layout is not visible. if (findOnPageLinearLayout.getVisibility() == View.GONE) { - appBar.show(); + actionBar.show(); } // Show the `BannerAd` in the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { // Initialize the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations. - AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id)); + AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), fragmentManager, getString(R.string.google_app_id), getString(R.string.ad_unit_id)); } - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); + // Remove any `SYSTEM_UI` flags from the coordinator layout. + coordinatorLayout.setSystemUiVisibility(0); // Remove the translucent navigation bar flag if it is set. getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); @@ -1171,8 +1153,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - // Constrain `rootCoordinatorLayout` inside the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(true); + // Constrain the coordinator layout inside the status and navigation bars. + coordinatorLayout.setFitsSystemWindows(true); + + // Show the action bar. + actionBar.show(); } // Show the ad if this is the free flavor. @@ -1224,17 +1209,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_FILE); // Show the download location permission alert dialog. The permission will be requested when the the dialog is closed. - downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location)); + downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location)); } else { // Show the permission request directly. // Request the permission. The download dialog will be launched by `onRequestPermissionResult()`. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_FILE_REQUEST_CODE); } } else { // The storage permission has already been granted. // Get a handle for the download file alert dialog. - AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(url, contentDisposition, contentLength); + DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(url, contentDisposition, contentLength); // Show the download file alert dialog. - downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download)); + downloadFileDialogFragment.show(fragmentManager, getString(R.string.download)); } } }); @@ -1611,8 +1596,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook httpAuthHandler = handler; // Display the HTTP authentication dialog. - AppCompatDialogFragment httpAuthenticationDialogFragment = HttpAuthenticationDialog.displayDialog(host, realm); - httpAuthenticationDialogFragment.show(supportFragmentManager, getString(R.string.http_authentication)); + DialogFragment httpAuthenticationDialogFragment = HttpAuthenticationDialog.displayDialog(host, realm); + httpAuthenticationDialogFragment.show(fragmentManager, getString(R.string.http_authentication)); } // Update the URL in urlTextBox when the page starts to load. @@ -1819,8 +1804,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook sslErrorHandler = handler; // Display the SSL error `AlertDialog`. - AppCompatDialogFragment sslCertificateErrorDialogFragment = SslCertificateErrorDialog.displayDialog(error); - sslCertificateErrorDialogFragment.show(supportFragmentManager, getString(R.string.ssl_certificate_error)); + DialogFragment sslCertificateErrorDialogFragment = SslCertificateErrorDialog.displayDialog(error); + sslCertificateErrorDialogFragment.show(fragmentManager, getString(R.string.ssl_certificate_error)); } } }); @@ -1888,6 +1873,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Load the URL. loadUrl(formattedUrlString); + // Get a handle for the drawer layout. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + // Close the navigation drawer if it is open. if (drawerLayout.isDrawerVisible(GravityCompat.START)) { drawerLayout.closeDrawer(GravityCompat.START); @@ -1957,6 +1945,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Update the bookmarks drawer if returning from the Bookmarks activity. if (restartFromBookmarksActivity) { + // Get a handle for the drawer layout. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + // Close the bookmarks drawer. drawerLayout.closeDrawer(GravityCompat.END); @@ -1999,6 +1990,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } if (displayingFullScreenVideo) { + // Get handles for the layouts that need to be modified. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorlayout); + // Remove the translucent overlays. getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); @@ -2009,7 +2004,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown. */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } } @@ -2118,6 +2113,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public boolean onPrepareOptionsMenu(Menu menu) { + // Get a handle for the swipe refresh layout. + SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); + // Get handles for the menu items. MenuItem addOrEditDomain = menu.findItem(R.id.add_or_edit_domain); MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies); @@ -2483,21 +2481,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { + @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`. @Override public void onDismissed(Snackbar snackbar, int event) { switch (event) { - // The user pushed the `Undo` button. + // The user pushed the undo button. case Snackbar.Callback.DISMISS_EVENT_ACTION: // Do nothing. break; - // The `Snackbar` was dismissed without the `Undo` button being pushed. + // The snackbar was dismissed without the undo button being pushed. default: // `cookieManager.removeAllCookie()` varies by SDK. if (Build.VERSION.SDK_INT < 21) { cookieManager.removeAllCookie(); } else { - // `null` indicates no callback. cookieManager.removeAllCookies(null); } } @@ -2512,15 +2510,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { + @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`. @Override public void onDismissed(Snackbar snackbar, int event) { switch (event) { - // The user pushed the `Undo` button. + // The user pushed the undo button. case Snackbar.Callback.DISMISS_EVENT_ACTION: // Do nothing. break; - // The `Snackbar` was dismissed without the `Undo` button being pushed. + // The snackbar was dismissed without the undo button being pushed. default: // Delete the DOM Storage. WebStorage webStorage = WebStorage.getInstance(); @@ -2567,15 +2566,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { + @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`. @Override public void onDismissed(Snackbar snackbar, int event) { switch (event) { - // The user pushed the `Undo` button. + // The user pushed the undo button. case Snackbar.Callback.DISMISS_EVENT_ACTION: // Do nothing. break; - // The `Snackbar` was dismissed without the `Undo` button being pushed. + // The snackbar was dismissed without the `Undo` button being pushed. default: // Delete the form data. WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(getApplicationContext()); @@ -2793,6 +2793,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook return true; case R.id.swipe_to_refresh: + // Get a handle for the swipe refresh layout. + SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); + // Toggle swipe to refresh. swipeRefreshLayout.setEnabled(!swipeRefreshLayout.isEnabled()); return true; @@ -2836,8 +2839,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook return true; case R.id.find_on_page: + // Get a handle for the toolbar. + Toolbar toolbar = findViewById(R.id.toolbar); + // Hide the URL app bar. - supportAppBar.setVisibility(View.GONE); + toolbar.setVisibility(View.GONE); // Show the Find on Page `RelativeLayout`. findOnPageLinearLayout.setVisibility(View.VISIBLE); @@ -2896,8 +2902,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case R.id.add_to_homescreen: // Show the alert dialog. - AppCompatDialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog(); - createHomeScreenShortcutDialogFragment.show(supportFragmentManager, getString(R.string.create_shortcut)); + DialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog(); + createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut)); //Everything else will be handled by the alert dialog and the associated listener below. return true; @@ -2923,7 +2929,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case R.id.ad_consent: // Display the ad consent dialog. DialogFragment adConsentDialogFragment = new AdConsentDialog(); - adConsentDialogFragment.show(getFragmentManager(), getString(R.string.ad_consent)); + adConsentDialogFragment.show(getSupportFragmentManager(), getString(R.string.ad_consent)); return true; default: @@ -2973,9 +2979,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the `WebBackForwardList`. WebBackForwardList webBackForwardList = mainWebView.copyBackForwardList(); - // Show the `UrlHistoryDialog` `AlertDialog` and name this instance `R.string.history`. `this` is the `Context`. - AppCompatDialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(this, webBackForwardList); - urlHistoryDialogFragment.show(supportFragmentManager, getString(R.string.history)); + // Show the URL history dialog and name this instance `R.string.history`. + DialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(this, webBackForwardList); + urlHistoryDialogFragment.show(getSupportFragmentManager(), getString(R.string.history)); break; case R.id.requests: @@ -3156,9 +3162,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Clear `customHeaders`. customHeaders.clear(); - // Detach all views from `mainWebViewRelativeLayout`. - mainWebViewRelativeLayout.removeAllViews(); - // Destroy the internal state of `mainWebView`. mainWebView.destroy(); @@ -3188,6 +3191,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook break; } + // Get a handle for the drawer layout. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + // Close the navigation drawer. drawerLayout.closeDrawer(GravityCompat.START); return true; @@ -3195,10 +3201,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onPostCreate(Bundle savedInstanceState) { + // Run the default commands. super.onPostCreate(savedInstanceState); // Sync the state of the DrawerToggle after onRestoreInstanceState has finished. - drawerToggle.syncState(); + actionBarDrawerToggle.syncState(); } @Override @@ -3237,8 +3244,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook final String imageUrl; final String linkUrl; - // Get a handle for the `ClipboardManager`. + // Get a handle for the the clipboard and fragment managers. final ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + FragmentManager fragmentManager = getSupportFragmentManager(); // Remove the lint errors below that `clipboardManager` might be `null`. assert clipboardManager != null; @@ -3287,17 +3295,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_FILE); // Show the download location permission alert dialog. The permission will be requested when the the dialog is closed. - downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location)); + downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location)); } else { // Show the permission request directly. // Request the permission. The download dialog will be launched by `onRequestPermissionResult()`. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_FILE_REQUEST_CODE); } } else { // The storage permission has already been granted. // Get a handle for the download file alert dialog. - AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(linkUrl, "none", -1); + DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(linkUrl, "none", -1); // Show the download file alert dialog. - downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download)); + downloadFileDialogFragment.show(fragmentManager, getString(R.string.download)); } } return false; @@ -3387,17 +3395,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE); // Show the download location permission alert dialog. The permission will be requested when the dialog is closed. - downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location)); + downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location)); } else { // Show the permission request directly. // Request the permission. The download dialog will be launched by `onRequestPermissionResult(). ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_IMAGE_REQUEST_CODE); } } else { // The storage permission has already been granted. // Get a handle for the download image alert dialog. - AppCompatDialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl); + DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl); // Show the download image alert dialog. - downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download)); + downloadImageDialogFragment.show(fragmentManager, getString(R.string.download)); } } return false; @@ -3461,17 +3469,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE); // Show the download location permission alert dialog. The permission will be requested when the dialog is closed. - downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location)); + downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location)); } else { // Show the permission request directly. // Request the permission. The download dialog will be launched by `onRequestPermissionResult(). ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_IMAGE_REQUEST_CODE); } } else { // The storage permission has already been granted. // Get a handle for the download image alert dialog. - AppCompatDialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl); + DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl); // Show the download image alert dialog. - downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download)); + downloadImageDialogFragment.show(fragmentManager, getString(R.string.download)); } } return false; @@ -3506,7 +3514,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onCreateBookmark(AppCompatDialogFragment dialogFragment) { + public void onCreateBookmark(DialogFragment dialogFragment) { // Get the `EditTexts` from the `dialogFragment`. EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext); EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext); @@ -3537,7 +3545,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onCreateBookmarkFolder(AppCompatDialogFragment dialogFragment) { + public void onCreateBookmarkFolder(DialogFragment dialogFragment) { // Get handles for the views in `dialogFragment`. EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext); RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton); @@ -3582,7 +3590,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onCreateHomeScreenShortcut(AppCompatDialogFragment dialogFragment) { + public void onCreateHomeScreenShortcut(DialogFragment dialogFragment) { // Get the shortcut name. EditText shortcutNameEditText = dialogFragment.getDialog().findViewById(R.id.shortcut_name_edittext); String shortcutNameString = shortcutNameEditText.getText().toString(); @@ -3623,16 +3631,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + // Get a handle for the fragment manager. + FragmentManager fragmentManager = getSupportFragmentManager(); + switch (requestCode) { case DOWNLOAD_FILE_REQUEST_CODE: // Show the download file alert dialog. When the dialog closes, the correct command will be used based on the permission status. - AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(downloadUrl, downloadContentDisposition, downloadContentLength); + DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(downloadUrl, downloadContentDisposition, downloadContentLength); // On API 23, displaying the fragment must be delayed or the app will crash. if (Build.VERSION.SDK_INT == 23) { - new Handler().postDelayed(() -> downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download)), 500); + new Handler().postDelayed(() -> downloadFileDialogFragment.show(fragmentManager, getString(R.string.download)), 500); } else { - downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download)); + downloadFileDialogFragment.show(fragmentManager, getString(R.string.download)); } // Reset the download variables. @@ -3643,13 +3654,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case DOWNLOAD_IMAGE_REQUEST_CODE: // Show the download image alert dialog. When the dialog closes, the correct command will be used based on the permission status. - AppCompatDialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(downloadImageUrl); + DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(downloadImageUrl); // On API 23, displaying the fragment must be delayed or the app will crash. if (Build.VERSION.SDK_INT == 23) { - new Handler().postDelayed(() -> downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download)), 500); + new Handler().postDelayed(() -> downloadImageDialogFragment.show(fragmentManager, getString(R.string.download)), 500); } else { - downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download)); + downloadImageDialogFragment.show(fragmentManager, getString(R.string.download)); } // Reset the image URL variable. @@ -3659,7 +3670,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onDownloadImage(AppCompatDialogFragment dialogFragment, String imageUrl) { + public void onDownloadImage(DialogFragment dialogFragment, String imageUrl) { // Download the image if it has an HTTP or HTTPS URI. if (imageUrl.startsWith("http")) { // Get a handle for the system `DOWNLOAD_SERVICE`. @@ -3711,7 +3722,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onDownloadFile(AppCompatDialogFragment dialogFragment, String downloadUrl) { + public void onDownloadFile(DialogFragment dialogFragment, String downloadUrl) { // Download the file if it has an HTTP or HTTPS URI. if (downloadUrl.startsWith("http")) { // Get a handle for the system `DOWNLOAD_SERVICE`. @@ -3763,7 +3774,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) { + public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) { // Get handles for the views from `dialogFragment`. EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext); EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext); @@ -3794,7 +3805,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId) { + public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) { // Get handles for the views from `dialogFragment`. EditText editFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_folder_name_edittext); RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton); @@ -3862,7 +3873,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } @Override - public void onHttpAuthenticationProceed(AppCompatDialogFragment dialogFragment) { + public void onHttpAuthenticationProceed(DialogFragment dialogFragment) { // Get handles for the `EditTexts`. EditText usernameEditText = dialogFragment.getDialog().findViewById(R.id.http_authentication_username); EditText passwordEditText = dialogFragment.getDialog().findViewById(R.id.http_authentication_password); @@ -3874,7 +3885,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook public void viewSslCertificate(View view) { // Show the `ViewSslCertificateDialog` `AlertDialog` and name this instance `@string/view_ssl_certificate`. DialogFragment viewSslCertificateDialogFragment = new ViewSslCertificateDialog(); - viewSslCertificateDialogFragment.show(getFragmentManager(), getString(R.string.view_ssl_certificate)); + viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate)); } @Override @@ -3931,6 +3942,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Override `onBackPressed` to handle the navigation drawer and `mainWebView`. @Override public void onBackPressed() { + // Get a handle for the drawer layout. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + if (drawerLayout.isDrawerVisible(GravityCompat.START)) { // The navigation drawer is open. // Close the navigation drawer. drawerLayout.closeDrawer(GravityCompat.START); @@ -4073,8 +4087,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide the Find on Page `RelativeLayout`. findOnPageLinearLayout.setVisibility(View.GONE); - // Show the URL app bar. - supportAppBar.setVisibility(View.VISIBLE); + // Get a handle for the toolbar. + Toolbar toolbar = findViewById(R.id.toolbar); + + // Show the toolbar. + toolbar.setVisibility(View.VISIBLE); // Hide the keyboard so we can see the webpage. `0` indicates no additional flags. inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); @@ -4103,6 +4120,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook customHeaders.remove("DNT"); } + // Get handles for the views that need to be modified. `getSupportActionBar()` must be used until the minimum API >= 21. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorlayout); + ActionBar actionBar = getSupportActionBar(); + // Apply the appropriate full screen mode the `SYSTEM_UI` flags. if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { // Privacy Browser is currently in full screen browsing mode. if (hideSystemBarsOnFullscreen) { // Hide everything. @@ -4119,10 +4141,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown. */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } else { // Hide everything except the status and navigation bars. - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); + // Remove any `SYSTEM_UI` flags from the coordinator layout. + coordinatorLayout.setSystemUiVisibility(0); // Add the translucent status flag if it is unset. getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); @@ -4139,19 +4161,22 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reset the full screen tracker, which could be true if Privacy Browser was in full screen mode before entering settings and full screen browsing was disabled. inFullScreenBrowsingMode = false; - // Show the `appBar` if `findOnPageLinearLayout` is not visible. + // Remove the incorrect lint warning below that the action bar might be null. + assert actionBar != null; + + // Show the action bar if the find on page linear layout is not visible. if (findOnPageLinearLayout.getVisibility() == View.GONE) { - appBar.show(); + actionBar.show(); } // Show the `BannerAd` in the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { // Initialize the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations. - AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id)); + AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), fragmentManager, getString(R.string.google_app_id), getString(R.string.ad_unit_id)); } - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); + // Remove any `SYSTEM_UI` flags from the coordinator layout. + coordinatorLayout.setSystemUiVisibility(0); // Remove the translucent navigation bar flag if it is set. getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); @@ -4159,8 +4184,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - // Constrain `rootCoordinatorLayout` inside the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(true); + // Constrain the coordinator layout inside the status and navigation bars. + coordinatorLayout.setFitsSystemWindows(true); } } @@ -4211,6 +4236,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook favoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(favoriteIconBitmap, 64, 64, true)); } + // Get a handle for the swipe refresh layout. + SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); + // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0); @@ -4556,6 +4584,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook if (mainMenu != null) { updatePrivacyIcons(true); } + + // TODO. + swipeRefreshLayout.setEnabled(false); } // Reload the website if returning from the Domains activity. @@ -4579,6 +4610,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String searchString = sharedPreferences.getString("search", getString(R.string.search_default_value)); String searchCustomUrlString = sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)); + // Get a handle for the action bar. `getSupportActionBar()` must be used until the minimum API >= 21. + ActionBar actionBar = getSupportActionBar(); + + // Remove the incorrect lint warning later that the action bar might be null. + assert actionBar != null; + // Set the homepage, search, and proxy options. if (proxyThroughOrbot) { // Set the Tor options. // Set `torHomepageString` as `homepage`. @@ -4601,9 +4638,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the `appBar` background to indicate proxying through Orbot is enabled. `this` refers to the context. if (darkTheme) { - appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.dark_blue_30)); + actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.dark_blue_30)); } else { - appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.blue_50)); + actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.blue_50)); } // Check to see if Orbot is ready. @@ -4641,9 +4678,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the default `appBar` background. `this` refers to the context. if (darkTheme) { - appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_900)); + actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_900)); } else { - appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_100)); + actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_100)); } // Reset `waitingForOrbot. @@ -4923,10 +4960,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook !currentWebsiteSslEndDateString.equals(pinnedSslEndDateString)))) { // Get a handle for the pinned mismatch alert dialog. - AppCompatDialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(pinnedSslCertificate, pinnedIpAddresses); + DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(pinnedSslCertificate, pinnedIpAddresses); // Show the pinned mismatch alert dialog. - pinnedMismatchDialogFragment.show(supportFragmentManager, "Pinned Mismatch"); + pinnedMismatchDialogFragment.show(fragmentManager, "Pinned Mismatch"); } } } diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java index 098fd66f..4c42db79 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner . + * Copyright © 2018-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -23,10 +23,6 @@ import android.content.Context; import android.database.Cursor; import android.database.MatrixCursor; import android.os.Bundle; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.app.AppCompatDialogFragment; -import android.support.v7.widget.Toolbar; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; @@ -36,6 +32,11 @@ import android.widget.ResourceCursorAdapter; import android.widget.Spinner; import android.widget.TextView; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API >= 21. +import androidx.fragment.app.DialogFragment; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.adapters.RequestsArrayAdapter; import com.stoutner.privacybrowser.dialogs.ViewRequestDialog; @@ -67,9 +68,9 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi // Set the content view. setContentView(R.layout.requests_coordinatorlayout); - // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. - Toolbar requestsAppBar = findViewById(R.id.requests_toolbar); - setSupportActionBar(requestsAppBar); + // Use the AndroidX toolbar from until the minimum API is >= 21. + Toolbar toolbar = findViewById(R.id.requests_toolbar); + setSupportActionBar(toolbar); // Get a handle for the app bar and the list view. ActionBar appBar = getSupportActionBar(); @@ -244,7 +245,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi assert selectedRequestStringArray != null; // Show the request detail dialog. - AppCompatDialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray); + DialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray); viewRequestDialogFragment.show(getSupportFragmentManager(), getString(R.string.request_details)); } } \ 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 index cb4146da..2687ab1f 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -20,9 +20,10 @@ package com.stoutner.privacybrowser.activities; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.view.WindowManager; +import androidx.appcompat.app.AppCompatActivity; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.fragments.SettingsFragment; diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/ViewSourceActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/ViewSourceActivity.java index 62c704de..052750b8 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/ViewSourceActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/ViewSourceActivity.java @@ -29,11 +29,6 @@ import android.os.Build; import android.os.Bundle; import android.os.LocaleList; import android.preference.PreferenceManager; -import android.support.v4.app.NavUtils; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; @@ -49,6 +44,12 @@ import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; // The AndroidX toolbar must be used until the minimum API is >= 21. +import androidx.core.app.NavUtils; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.AboutViewSourceDialog; @@ -93,19 +94,19 @@ public class ViewSourceActivity extends AppCompatActivity { // Set the content view. setContentView(R.layout.view_source_coordinatorlayout); - // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21. - Toolbar viewSourceAppBar = findViewById(R.id.view_source_toolbar); - setSupportActionBar(viewSourceAppBar); + // The AndroidX toolbar must be used until the minimum API is >= 21. + Toolbar toolbar = findViewById(R.id.view_source_toolbar); + setSupportActionBar(toolbar); - // Setup the app bar. - final ActionBar appBar = getSupportActionBar(); + // Get a handle for the action bar. + final ActionBar actionBar = getSupportActionBar(); - // Remove the incorrect warning in Android Studio that appBar might be null. - assert appBar != null; + // Remove the incorrect lint warning that the action bar might be null. + assert actionBar != null; - // Add the custom layout to the app bar. - appBar.setCustomView(R.layout.view_source_app_bar); - appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); + // Add the custom layout to the action bar. + actionBar.setCustomView(R.layout.view_source_app_bar); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); // Get a handle for the url text box. EditText urlEditText = findViewById(R.id.url_edittext); diff --git a/app/src/main/java/com/stoutner/privacybrowser/adapters/HistoryArrayAdapter.java b/app/src/main/java/com/stoutner/privacybrowser/adapters/HistoryArrayAdapter.java index be6d11a8..5150fb32 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/adapters/HistoryArrayAdapter.java +++ b/app/src/main/java/com/stoutner/privacybrowser/adapters/HistoryArrayAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -21,7 +21,6 @@ package com.stoutner.privacybrowser.adapters; import android.content.Context; import android.graphics.Typeface; -import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,6 +28,8 @@ import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.definitions.History; diff --git a/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java b/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java index 62dec5d8..f6f1e8b4 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java +++ b/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner . + * Copyright © 2018-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -20,7 +20,6 @@ package com.stoutner.privacybrowser.adapters; import android.content.Context; -import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -28,6 +27,8 @@ import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; diff --git a/app/src/main/java/com/stoutner/privacybrowser/definitions/WrapVerticalContentViewPager.java b/app/src/main/java/com/stoutner/privacybrowser/definitions/WrapVerticalContentViewPager.java deleted file mode 100644 index 8b1d9782..00000000 --- a/app/src/main/java/com/stoutner/privacybrowser/definitions/WrapVerticalContentViewPager.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.stoutner.privacybrowser.definitions; - -/* - * Copyright © 2017 Soren Stoutner . - * - * This file is part of Privacy Browser . - * - * Privacy Browser is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Privacy Browser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Privacy Browser. If not, see . - */ - -import android.content.Context; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.View; - -public class WrapVerticalContentViewPager extends ViewPager { - // Setup the default constructors. - public WrapVerticalContentViewPager(Context context) { - super(context); - } - - public WrapVerticalContentViewPager(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Perform an initial `super.onMeasure`, which populates `getChildCount`. - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // Initialize `maximumHeight`. - int maximumHeight = 0; - - // Find the maximum height of each of the child views. - for (int i = 0; i < getChildCount(); i++) { - View childView = getChildAt(i); - - // Measure the child view height with no constraints. - childView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - - // Store the child's height if it is larger than `maximumHeight`. - if (childView.getMeasuredHeight() > maximumHeight) { - maximumHeight = childView.getMeasuredHeight(); - } - } - - // Perform a final `super.onMeasure` to set the `maximumHeight`. - super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maximumHeight, MeasureSpec.EXACTLY)); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/AddDomainDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/AddDomainDialog.java index edffc63f..cfba553e 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/AddDomainDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/AddDomainDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2018 Soren Stoutner . + * Copyright © 2017-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -26,9 +26,6 @@ import android.content.Context; import android.content.DialogInterface; import android.net.Uri; import android.os.Bundle; -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <= 22. -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -38,14 +35,18 @@ import android.widget.Button; import android.widget.EditText; import android.widget.TextView; +import androidx.annotation.NonNull; +// The AndroidX dialog fragment must be used or an error is produced on API <=22. +import androidx.fragment.app.DialogFragment; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; -public class AddDomainDialog extends AppCompatDialogFragment { +public class AddDomainDialog extends DialogFragment { // The public interface is used to send information back to the parent activity. public interface AddDomainListener { - void onAddDomain(AppCompatDialogFragment dialogFragment); + void onAddDomain(DialogFragment dialogFragment); } // `addDomainListener` is used in `onAttach()` and `onCreateDialog()`. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkDialog.java index d034aac7..60b4cef9 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -27,21 +27,21 @@ import android.content.DialogInterface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.NonNull; -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <= 22. -import android.support.v7.app.AppCompatDialogFragment; import android.view.KeyEvent; import android.view.View; import android.view.WindowManager; import android.widget.EditText; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.R; -public class CreateBookmarkDialog extends AppCompatDialogFragment { +public class CreateBookmarkDialog extends DialogFragment { // The public interface is used to send information back to the parent activity. public interface CreateBookmarkListener { - void onCreateBookmark(AppCompatDialogFragment dialogFragment); + void onCreateBookmark(DialogFragment dialogFragment); } // `createBookmarkListener` is used in `onAttach()` and `onCreateDialog()` diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java index 83aa93f9..7600db64 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java @@ -26,9 +26,6 @@ import android.content.Context; import android.content.DialogInterface; import android.database.Cursor; import android.os.Bundle; -import android.support.annotation.NonNull; -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -38,14 +35,17 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; -public class CreateBookmarkFolderDialog extends AppCompatDialogFragment { +public class CreateBookmarkFolderDialog extends DialogFragment { // The public interface is used to send information back to the parent activity. public interface CreateBookmarkFolderListener { - void onCreateBookmarkFolder(AppCompatDialogFragment dialogFragment); + void onCreateBookmarkFolder(DialogFragment dialogFragment); } // `createBookmarkFolderListener` is used in `onAttach()` and `onCreateDialog`. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateHomeScreenShortcutDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateHomeScreenShortcutDialog.java index ca8d72bd..cb9accc6 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateHomeScreenShortcutDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateHomeScreenShortcutDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2015-2018 Soren Stoutner . + * Copyright © 2015-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -27,22 +27,22 @@ import android.content.DialogInterface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.NonNull; -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.EditText; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.R; -public class CreateHomeScreenShortcutDialog extends AppCompatDialogFragment { +public class CreateHomeScreenShortcutDialog extends DialogFragment { // The public interface is used to send information back to the parent activity. public interface CreateHomeScreenShortcutListener { - void onCreateHomeScreenShortcut(AppCompatDialogFragment dialogFragment); + void onCreateHomeScreenShortcut(DialogFragment dialogFragment); } //`createHomeScreenShortcutListener` is used in `onAttach()` and `onCreateDialog()`. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadFileDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadFileDialog.java index 2ade1eae..1fd2fd77 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadFileDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadFileDialog.java @@ -26,9 +26,6 @@ import android.content.Context; import android.content.DialogInterface; import android.net.Uri; import android.os.Bundle; -import android.support.annotation.NonNull; -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -36,18 +33,21 @@ import android.view.WindowManager; import android.widget.EditText; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import java.util.Locale; -public class DownloadFileDialog extends AppCompatDialogFragment { +public class DownloadFileDialog extends DialogFragment { // `downloadFileListener` is used in `onAttach()` and `onCreateDialog()`. private DownloadFileListener downloadFileListener; // The public interface is used to send information back to the parent activity. public interface DownloadFileListener { - void onDownloadFile(AppCompatDialogFragment dialogFragment, String downloadUrl); + void onDownloadFile(DialogFragment dialogFragment, String downloadUrl); } @Override diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadImageDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadImageDialog.java index 94f25868..eb2624f3 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadImageDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadImageDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -26,27 +26,25 @@ import android.content.Context; import android.content.DialogInterface; import android.net.Uri; import android.os.Bundle; -import android.support.annotation.NonNull; -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <= 22. -import android.support.v7.app.AppCompatDialogFragment; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.EditText; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; -// `android.support.v7.app.AlertDialog` uses more of the horizontal screen real estate versus `android.app.AlertDialog's` smaller width. -// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22. -public class DownloadImageDialog extends AppCompatDialogFragment { +public class DownloadImageDialog extends DialogFragment { // `downloadImageListener` is used in `onAttach()` and `onCreateDialog()`. private DownloadImageListener downloadImageListener; // The public interface is used to send information back to the parent activity. public interface DownloadImageListener { - void onDownloadImage(AppCompatDialogFragment dialogFragment, String downloadUrl); + void onDownloadImage(DialogFragment dialogFragment, String downloadUrl); } // Check to make sure tha the parent activity implements the listener. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadLocationPermissionDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadLocationPermissionDialog.java index a2320588..c5059732 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadLocationPermissionDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadLocationPermissionDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner . + * Copyright © 2018-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -21,7 +21,6 @@ package com.stoutner.privacybrowser.dialogs; import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; @@ -30,6 +29,9 @@ import android.view.WindowManager; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + public class DownloadLocationPermissionDialog extends DialogFragment { // The constants are used to differentiate between the two download types. public static final int DOWNLOAD_FILE = 1; @@ -65,8 +67,12 @@ public class DownloadLocationPermissionDialog extends DialogFragment { return thisDownloadLocationPermissionDialog; } + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + // Remove the incorrect lint warning below that `getArguments().getInt()` might be null. + assert getArguments() != null; + // Store the download type in a local variable. int downloadType = getArguments().getInt("download_type"); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java index 5abda5b9..57ca9b4b 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java @@ -30,11 +30,6 @@ import android.database.MergeCursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; -import android.support.annotation.NonNull; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v4.content.ContextCompat; -import android.support.v4.widget.ResourceCursorAdapter; -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -46,6 +41,7 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.RadioButton; import android.widget.RadioGroup; +import android.widget.ResourceCursorAdapter; import android.widget.Spinner; import android.widget.TextView; @@ -53,7 +49,11 @@ import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; -public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment { +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + +public class EditBookmarkDatabaseViewDialog extends DialogFragment { // Instantiate the constants. public static final int HOME_FOLDER_DATABASE_ID = -1; @@ -72,7 +72,7 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment { // The public interface is used to send information back to the parent activity. public interface EditBookmarkDatabaseViewListener { - void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId); + void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId); } @Override diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java index 64efa611..3bfb796a 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java @@ -28,9 +28,6 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; -import android.support.annotation.NonNull; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -42,11 +39,14 @@ import android.widget.ImageView; import android.widget.RadioButton; import android.widget.RadioGroup; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; -public class EditBookmarkDialog extends AppCompatDialogFragment { +public class EditBookmarkDialog extends DialogFragment { // Instantiate the class variables. private EditBookmarkListener editBookmarkListener; private EditText nameEditText; @@ -58,7 +58,7 @@ public class EditBookmarkDialog extends AppCompatDialogFragment { // The public interface is used to send information back to the parent activity. public interface EditBookmarkListener { - void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId); + void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId); } public void onAttach(Context context) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java index 0f691433..e9eb51ea 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java @@ -31,11 +31,6 @@ import android.database.MergeCursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.support.v4.widget.ResourceCursorAdapter; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -47,14 +42,19 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.RadioButton; import android.widget.RadioGroup; +import android.widget.ResourceCursorAdapter; import android.widget.Spinner; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; -public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragment { +public class EditBookmarkFolderDatabaseViewDialog extends DialogFragment { // Instantiate the constants. public static final int HOME_FOLDER_DATABASE_ID = -1; @@ -73,7 +73,7 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen // The public interface is used to send information back to the parent activity. public interface EditBookmarkFolderDatabaseViewListener { - void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId); + void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId); } public void onAttach(Context context) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java index e854a065..e3606a79 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java @@ -28,9 +28,6 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; -import android.support.annotation.NonNull; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -42,17 +39,20 @@ import android.widget.ImageView; import android.widget.RadioButton; import android.widget.RadioGroup; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; -public class EditBookmarkFolderDialog extends AppCompatDialogFragment { +public class EditBookmarkFolderDialog extends DialogFragment { // Instantiate the class variable. private EditBookmarkFolderListener editBookmarkFolderListener; // The public interface is used to send information back to the parent activity. public interface EditBookmarkFolderListener { - void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId); + void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId); } public void onAttach(Context context) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.java index 46af64e7..6099d2b3 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2018 Soren Stoutner . + * Copyright © 2017-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -25,9 +25,6 @@ import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; -import android.support.annotation.NonNull; -// `AppCompatDialogFragment` is used instead of `DialogFragment` to avoid an error on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; @@ -41,7 +38,10 @@ import android.widget.TextView; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; -public class HttpAuthenticationDialog extends AppCompatDialogFragment{ +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + +public class HttpAuthenticationDialog extends DialogFragment{ // `httpAuthenticationListener` is used in `onAttach()` and `onCreateDialog()` private HttpAuthenticationListener httpAuthenticationListener; @@ -49,7 +49,7 @@ public class HttpAuthenticationDialog extends AppCompatDialogFragment{ public interface HttpAuthenticationListener { void onHttpAuthenticationCancel(); - void onHttpAuthenticationProceed(AppCompatDialogFragment dialogFragment); + void onHttpAuthenticationProceed(DialogFragment dialogFragment); } public void onAttach(Context context) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java index 28d0fa55..9f57519e 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java @@ -33,10 +33,6 @@ import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -// `AppCompatDialogFragment` must be used instead of `DialogFragment` or an error is produced on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -47,6 +43,10 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <= 22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.BookmarksActivity; import com.stoutner.privacybrowser.activities.MainWebViewActivity; @@ -54,7 +54,7 @@ import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; import java.io.ByteArrayOutputStream; -public class MoveToFolderDialog extends AppCompatDialogFragment { +public class MoveToFolderDialog extends DialogFragment { // Instantiate the class variables. private MoveToFolderListener moveToFolderListener; private BookmarksDatabaseHelper bookmarksDatabaseHelper; @@ -62,7 +62,7 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { // The public interface is used to send information back to the parent activity. public interface MoveToFolderListener { - void onMoveToFolder(AppCompatDialogFragment dialogFragment); + void onMoveToFolder(DialogFragment dialogFragment); } public void onAttach(Context context) { @@ -78,7 +78,7 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { @Override @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { - // Initialize the database helper. The two `nulls` do not specify the database name or a `CursorFactory`. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`. + // Initialize the database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`. bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0); // Use an alert dialog builder to create the alert dialog. @@ -303,4 +303,4 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { addSubfoldersToExceptFolders(subfolderName); } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java index 0a25771d..e1c035ae 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java @@ -29,11 +29,6 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.http.SslCertificate; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.design.widget.TabLayout; -import android.support.v4.view.PagerAdapter; -// `AppCompatDialogFragment` is used instead of `DialogFragment` to avoid an error on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; @@ -43,15 +38,21 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.widget.TextView; +import com.google.android.material.tabs.TabLayout; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; -import com.stoutner.privacybrowser.definitions.WrapVerticalContentViewPager; +import com.stoutner.privacybrowser.views.WrapVerticalContentViewPager; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; import java.text.DateFormat; import java.util.Date; -public class PinnedMismatchDialog extends AppCompatDialogFragment { +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. +import androidx.viewpager.widget.PagerAdapter; + +public class PinnedMismatchDialog extends DialogFragment { // Instantiate the class variables. private PinnedMismatchListener pinnedMismatchListener; private LayoutInflater layoutInflater; diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java index 4faafcba..56c9d021 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java @@ -31,10 +31,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.DocumentsContract; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. It is also required for the browser button to work correctly. -import android.support.v7.app.AppCompatDialogFragment; import android.text.Editable; import android.text.TextWatcher; import android.view.View; @@ -46,14 +42,18 @@ import android.widget.TextView; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; -public class SaveLogcatDialog extends AppCompatDialogFragment { +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment is required or an error is produced on API <=22. It is also required for the browse button to work correctly. + +public class SaveLogcatDialog extends DialogFragment { // Instantiate the class variables. private SaveLogcatListener saveLogcatListener; private Context parentContext; // The public interface is used to send information back to the parent activity. public interface SaveLogcatListener { - void onSaveLogcat(AppCompatDialogFragment dialogFragment); + void onSaveLogcat(DialogFragment dialogFragment); } public void onAttach(Context context) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.java index 76732ff2..602ee2c9 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.java @@ -30,9 +30,6 @@ import android.net.http.SslCertificate; import android.net.http.SslError; import android.os.AsyncTask; import android.os.Bundle; -import android.support.annotation.NonNull; -// `AppCompatDialogFragment` is used instead of `DialogFragment` to avoid an error on API <=22. -import android.support.v7.app.AppCompatDialogFragment; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; @@ -40,6 +37,9 @@ import android.view.LayoutInflater; import android.view.WindowManager; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; @@ -49,7 +49,7 @@ import java.net.UnknownHostException; import java.text.DateFormat; import java.util.Date; -public class SslCertificateErrorDialog extends AppCompatDialogFragment { +public class SslCertificateErrorDialog extends DialogFragment { // `sslCertificateErrorListener` is used in `onAttach` and `onCreateDialog`. private SslCertificateErrorListener sslCertificateErrorListener; diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/StoragePermissionDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/StoragePermissionDialog.java index ed119595..fbff4d29 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/StoragePermissionDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/StoragePermissionDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner . + * Copyright © 2018-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -24,15 +24,15 @@ import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; -// `AppCompatDialogFragment` must be used instead of `DialogFragment` or the browse button doesn't work correctly in the other dialog for saving logcats. -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatDialogFragment; import android.view.WindowManager; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; -public class StoragePermissionDialog extends AppCompatDialogFragment { +public class StoragePermissionDialog extends DialogFragment { // The listener is used in `onAttach()` and `onCreateDialog()`. private StoragePermissionDialogListener storagePermissionDialogListener; diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java index a593f5cf..0fe8afaa 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java @@ -29,11 +29,6 @@ import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -// `AppCompatDialogFragment` must be used instead of `DialogFragment` or an error is produced on API <= 22. -// `android.support.v7.app.AlertDialog` also uses more of the horizontal screen real estate versus `android.app.AlertDialog's` smaller width. -import android.support.v7.app.AppCompatDialogFragment; import android.util.Base64; import android.view.LayoutInflater; import android.view.View; @@ -42,6 +37,10 @@ import android.webkit.WebBackForwardList; import android.widget.AdapterView; import android.widget.ListView; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.adapters.HistoryArrayAdapter; @@ -50,7 +49,7 @@ import com.stoutner.privacybrowser.definitions.History; import java.io.ByteArrayOutputStream; import java.util.ArrayList; -public class UrlHistoryDialog extends AppCompatDialogFragment{ +public class UrlHistoryDialog extends DialogFragment{ // `historyArrayList` and `currentPageId` pass information from `onCreate()` to `onCreateDialog()`. private final ArrayList historyArrayList = new ArrayList<>(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java index 86b4f953..6d6401f3 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner . + * Copyright © 2018-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -25,17 +25,18 @@ import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatDialogFragment; import android.view.View; import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; -public class ViewRequestDialog extends AppCompatDialogFragment { +public class ViewRequestDialog extends DialogFragment { // The public interface is used to send information back to the parent activity. public interface ViewRequestListener { void onPrevious(int id); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewSslCertificateDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewSslCertificateDialog.java index 73ad2ce8..c99eeba0 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewSslCertificateDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewSslCertificateDialog.java @@ -22,7 +22,6 @@ package com.stoutner.privacybrowser.dialogs; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -35,6 +34,9 @@ import android.view.LayoutInflater; import android.view.WindowManager; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22. + import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.R; import java.text.DateFormat; @@ -44,7 +46,11 @@ import java.util.Date; // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`. @SuppressLint("InflateParams") public class ViewSslCertificateDialog extends DialogFragment { + @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { + // Remove the incorrect lint warning below that the activity might be null. + assert getActivity() != null; + // Get the activity's layout inflater. LayoutInflater layoutInflater = getActivity().getLayoutInflater(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java index 2f206fe0..91cb7dc6 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -25,8 +25,6 @@ import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.Build; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.app.Fragment; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; @@ -36,6 +34,9 @@ import android.view.ViewGroup; import android.webkit.WebView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + import com.stoutner.privacybrowser.BuildConfig; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java index 614bb374..f08f343f 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java @@ -28,10 +28,6 @@ import android.net.http.SslCertificate; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.annotation.NonNull; -// `android.support.v4.app.Fragment` must be used until minimum API >= 23. Otherwise `getContext()` does not work. -import android.support.v4.app.Fragment; -import android.support.v7.widget.CardView; import android.text.Editable; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -52,6 +48,10 @@ import android.widget.Spinner; import android.widget.Switch; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.fragment.app.Fragment; // The AndroidX fragment must be used until minimum API >= 23. Otherwise `getContext()` does not work. + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainsListFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainsListFragment.java index 8f50d2fc..b28289b0 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainsListFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainsListFragment.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2018 Soren Stoutner . + * Copyright © 2017-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -20,17 +20,18 @@ package com.stoutner.privacybrowser.fragments; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.design.widget.FloatingActionButton; -// `android.support.v4.app.Fragment` must be used until minimum API >= 23. Otherwise `getContext()` cannot be called. -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; // The AndroidX fragment must be used until minimum API >= 23. Otherwise `getContext()` does not work. +import androidx.fragment.app.FragmentManager; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.DomainsActivity; import com.stoutner.privacybrowser.activities.MainWebViewActivity; @@ -59,8 +60,14 @@ public class DomainsListFragment extends Fragment { // Save the current domain settings if operating in two-paned mode and a domain is currently selected. if (DomainsActivity.twoPanedMode && DomainsActivity.deleteMenuItem.isEnabled()) { + // Get a handle for the domain settings fragment. + Fragment domainSettingsFragment = supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container); + + // Remove the incorrect lint error below that the domain settings fragment might be null. + assert domainSettingsFragment != null; + // Get a handle for the domain settings fragment view. - View domainSettingsFragmentView = supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container).getView(); + View domainSettingsFragmentView = domainSettingsFragment.getView(); // Get a handle for the domains activity. DomainsActivity domainsActivity = new DomainsActivity(); @@ -105,7 +112,7 @@ public class DomainsListFragment extends Fragment { // Hide the add domain FAB. FloatingActionButton addDomainFAB = getActivity().findViewById(R.id.add_domain_fab); - addDomainFAB.setVisibility(View.GONE); + addDomainFAB.hide(); // Display the domain settings fragment. supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/GuideTabFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/GuideTabFragment.java index d22006cd..4a417b64 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/GuideTabFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/GuideTabFragment.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -21,13 +21,14 @@ package com.stoutner.privacybrowser.fragments; import android.annotation.SuppressLint; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.WebView; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java index 9852dd0b..37173545 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner . + * Copyright © 2016-2019 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -26,10 +26,11 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Proxy; -import android.support.v7.app.AlertDialog; import android.util.ArrayMap; import android.util.Log; +import androidx.appcompat.app.AlertDialog; + import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.R; diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java b/app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java index e9bc8047..06187dbf 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java +++ b/app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java @@ -40,12 +40,13 @@ package com.stoutner.privacybrowser.views; import android.content.Context; -import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.widget.Checkable; import android.widget.LinearLayout; +import androidx.annotation.Nullable; + public class CheckedLinearLayout extends LinearLayout implements Checkable { private boolean isCurrentlyChecked; private static final int[] CHECKED_STATE_SET = { diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java new file mode 100644 index 00000000..ea94571a --- /dev/null +++ b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java @@ -0,0 +1,220 @@ +/* + * Copyright © 2019 Soren Stoutner . + * + * This file is part of Privacy Browser . + * + * Privacy Browser is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser. If not, see . + */ + +package com.stoutner.privacybrowser.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.webkit.WebView; + +import androidx.core.view.NestedScrollingChild2; +import androidx.core.view.NestedScrollingChildHelper; +import androidx.core.view.ViewCompat; + +// NestedScrollWebView extends WebView to handle nested scrolls (scrolling the app bar off the screen). +public class NestedScrollWebView extends WebView implements NestedScrollingChild2 { + // The nested scrolling child helper is used throughout the class. + private NestedScrollingChildHelper nestedScrollingChildHelper; + + // The previous Y position needs to be tracked between motion events. + private int previousYPosition; + + + // Basic constructor. + public NestedScrollWebView(Context context) { + // Roll up to the next constructor. + this(context, null); + } + + // Intermediate constructor. + public NestedScrollWebView(Context context, AttributeSet attributeSet) { + // Roll up to the next constructor. + this(context, attributeSet, android.R.attr.webViewStyle); + } + + // Full constructor. + public NestedScrollWebView(Context context, AttributeSet attributeSet, int defaultStyle) { + // Run the default commands. + super(context, attributeSet, defaultStyle); + + // Initialize the nested scrolling child helper. + nestedScrollingChildHelper = new NestedScrollingChildHelper(this); + + // Enable nested scrolling by default. + nestedScrollingChildHelper.setNestedScrollingEnabled(true); + } + + + @Override + public boolean onTouchEvent(MotionEvent motionEvent) { + // Initialize a tracker to return if this motion event is handled. + boolean motionEventHandled; + + // Run the commands for the given motion event action. + switch (motionEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + // Start nested scrolling along the vertical axis. `ViewCompat` must be used until the minimum API >= 21. + startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); + + // Save the current Y position. Action down will not be called again until a new motion starts. + previousYPosition = (int) motionEvent.getY(); + + // Run the default commands. + motionEventHandled = super.onTouchEvent(motionEvent); + break; + + case MotionEvent.ACTION_MOVE: + // Get the current Y position. + int currentYPosition = (int) motionEvent.getY(); + + // Calculate the delta Y. + int deltaY = previousYPosition - currentYPosition; + + // Store the current Y position for use in the next action move. + previousYPosition = currentYPosition; + + // Dispatch the nested pre-school. + dispatchNestedPreScroll(0, deltaY, null, null); + + // Dispatch the nested scroll. + dispatchNestedScroll(0, deltaY, 0, 0, null); + + // Run the default commands. + motionEventHandled = super.onTouchEvent(motionEvent); + break; + + + default: + // Stop nested scrolling. + stopNestedScroll(); + + // Run the default commands. + motionEventHandled = super.onTouchEvent(motionEvent); + } + + // Return the status of the motion event. + return motionEventHandled; + } + + + // Method from NestedScrollingChild. + @Override + public void setNestedScrollingEnabled(boolean status) { + // Set the status of the nested scrolling. + nestedScrollingChildHelper.setNestedScrollingEnabled(status); + } + + // Method from NestedScrollingChild. + @Override + public boolean isNestedScrollingEnabled() { + // Return the status of nested scrolling. + return nestedScrollingChildHelper.isNestedScrollingEnabled(); + } + + + // Method from NestedScrollingChild. + @Override + public boolean startNestedScroll(int axes) { + // Start a nested scroll along the indicated axes. + return nestedScrollingChildHelper.startNestedScroll(axes); + } + + // Method from NestedScrollingChild2. + @Override + public boolean startNestedScroll(int axes, int type) { + // Start a nested scroll along the indicated axes for the given type of input which caused the scroll event. + return nestedScrollingChildHelper.startNestedScroll(axes, type); + } + + + // Method from NestedScrollingChild. + @Override + public void stopNestedScroll() { + // Stop the nested scroll. + nestedScrollingChildHelper.stopNestedScroll(); + } + + // Method from NestedScrollingChild2. + @Override + public void stopNestedScroll(int type) { + // Stop the nested scroll of the given type of input which caused the scroll event. + nestedScrollingChildHelper.stopNestedScroll(type); + } + + + // Method from NestedScrollingChild. + @Override + public boolean hasNestedScrollingParent() { + // Return the status of the nested scrolling parent. + return nestedScrollingChildHelper.hasNestedScrollingParent(); + } + + // Method from NestedScrollingChild2. + @Override + public boolean hasNestedScrollingParent(int type) { + // return the status of the nested scrolling parent for the given type of input which caused the scroll event. + return nestedScrollingChildHelper.hasNestedScrollingParent(type); + } + + + // Method from NestedScrollingChild. + @Override + public boolean dispatchNestedPreScroll(int deltaX, int deltaY, int[] consumed, int[] offsetInWindow) { + // Dispatch a nested pre-scroll with the specified deltas, which lets a parent to consume some of the scroll if desired. + return nestedScrollingChildHelper.dispatchNestedPreScroll(deltaX, deltaY, consumed, offsetInWindow); + } + + // Method from NestedScrollingChild2. + @Override + public boolean dispatchNestedPreScroll(int deltaX, int deltaY, int[] consumed, int[] offsetInWindow, int type) { + // Dispatch a nested pre-scroll with the specified deltas for the given type of input which caused the scroll event, which lets a parent to consume some of the scroll if desired. + return nestedScrollingChildHelper.dispatchNestedPreScroll(deltaX, deltaY, consumed, offsetInWindow, type); + } + + + // Method from NestedScrollingChild. + @Override + public boolean dispatchNestedScroll(int deltaXConsumed, int deltaYConsumed, int deltaXUnconsumed, int deltaYUnconsumed, int[] offsetInWindow) { + // Dispatch a nested scroll with the specified deltas. + return nestedScrollingChildHelper.dispatchNestedScroll(deltaXConsumed, deltaYConsumed, deltaXUnconsumed, deltaYUnconsumed, offsetInWindow); + } + + // Method from NestedScrollingChild2. + @Override + public boolean dispatchNestedScroll(int deltaXConsumed, int deltaYConsumed, int deltaXUnconsumed, int deltaYUnconsumed, int[] offsetInWindow, int type) { + // Dispatch a nested scroll with the specified deltas for the given type of input which caused the scroll event. + return nestedScrollingChildHelper.dispatchNestedScroll(deltaXConsumed, deltaYConsumed, deltaXUnconsumed, deltaYUnconsumed, offsetInWindow, type); + } + + + // Method from NestedScrollingChild. + @Override + public boolean dispatchNestedPreFling(float velocityX, float velocityY) { + // Dispatch a nested pre-fling with the specified velocity, which lets a parent consume the fling if desired. + return nestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY); + } + + // Method from NestedScrollingChild. + @Override + public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { + // Dispatch a nested fling with the specified velocity. + return nestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/WrapVerticalContentViewPager.java b/app/src/main/java/com/stoutner/privacybrowser/views/WrapVerticalContentViewPager.java new file mode 100644 index 00000000..7e297251 --- /dev/null +++ b/app/src/main/java/com/stoutner/privacybrowser/views/WrapVerticalContentViewPager.java @@ -0,0 +1,62 @@ +/* + * Copyright © 2017,2019 Soren Stoutner . + * + * This file is part of Privacy Browser . + * + * Privacy Browser is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser. If not, see . + */ + +package com.stoutner.privacybrowser.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +import androidx.viewpager.widget.ViewPager; + +public class WrapVerticalContentViewPager extends ViewPager { + // Setup the default constructors. + public WrapVerticalContentViewPager(Context context) { + super(context); + } + + public WrapVerticalContentViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // Perform an initial `super.onMeasure`, which populates `getChildCount`. + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + // Initialize `maximumHeight`. + int maximumHeight = 0; + + // Find the maximum height of each of the child views. + for (int i = 0; i < getChildCount(); i++) { + View childView = getChildAt(i); + + // Measure the child view height with no constraints. + childView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + + // Store the child's height if it is larger than `maximumHeight`. + if (childView.getMeasuredHeight() > maximumHeight) { + maximumHeight = childView.getMeasuredHeight(); + } + } + + // Perform a final `super.onMeasure` to set the `maximumHeight`. + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maximumHeight, MeasureSpec.EXACTLY)); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout-w900dp/bookmarks_drawer.xml b/app/src/main/res/layout-w900dp/bookmarks_drawer.xml index 2b7073ef..aafac66e 100644 --- a/app/src/main/res/layout-w900dp/bookmarks_drawer.xml +++ b/app/src/main/res/layout-w900dp/bookmarks_drawer.xml @@ -49,7 +49,7 @@ android:dividerHeight="0dp" /> - - - . --> - - - - - - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/add_domain_dialog.xml b/app/src/main/res/layout/add_domain_dialog.xml index dff393cb..d69a4488 100644 --- a/app/src/main/res/layout/add_domain_dialog.xml +++ b/app/src/main/res/layout/add_domain_dialog.xml @@ -1,7 +1,7 @@ - + - - + - - - - + @@ -59,7 +59,7 @@ android:dividerHeight="1dp" /> - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml b/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml index 378a71e1..298c5796 100644 --- a/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml +++ b/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml @@ -21,7 +21,7 @@ - - - - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml b/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml index 7911f31d..85031f9b 100644 --- a/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml +++ b/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml @@ -1,7 +1,7 @@ - + - - + - - + - - + \ No newline at end of file diff --git a/app/src/main/res/layout/create_bookmark_folder_dialog.xml b/app/src/main/res/layout/create_bookmark_folder_dialog.xml index 53bf6dcf..f6cdc692 100644 --- a/app/src/main/res/layout/create_bookmark_folder_dialog.xml +++ b/app/src/main/res/layout/create_bookmark_folder_dialog.xml @@ -1,7 +1,7 @@ - + - - + + - - + \ No newline at end of file diff --git a/app/src/main/res/layout/domain_settings_fragment.xml b/app/src/main/res/layout/domain_settings_fragment.xml index 74e76de9..1c706fb2 100644 --- a/app/src/main/res/layout/domain_settings_fragment.xml +++ b/app/src/main/res/layout/domain_settings_fragment.xml @@ -56,20 +56,20 @@ android:tint="?attr/domainSettingsIconTintColor" tools:ignore="contentDescription" /> - - + - - + - - + - - + - - + - - + \ No newline at end of file diff --git a/app/src/main/res/layout/domains_coordinatorlayout.xml b/app/src/main/res/layout/domains_coordinatorlayout.xml index c875f44c..69aabd8b 100644 --- a/app/src/main/res/layout/domains_coordinatorlayout.xml +++ b/app/src/main/res/layout/domains_coordinatorlayout.xml @@ -1,7 +1,7 @@ - -true` to make the status bar a transparent, darkened overlay. --> + - - - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/download_file_dialog.xml b/app/src/main/res/layout/download_file_dialog.xml index 01eddd96..d3812fc4 100644 --- a/app/src/main/res/layout/download_file_dialog.xml +++ b/app/src/main/res/layout/download_file_dialog.xml @@ -1,7 +1,7 @@ - + - - + - + - + - - + - + \ No newline at end of file diff --git a/app/src/main/res/layout/edit_bookmark_databaseview_dialog.xml b/app/src/main/res/layout/edit_bookmark_databaseview_dialog.xml index f690f9c8..a03d0095 100644 --- a/app/src/main/res/layout/edit_bookmark_databaseview_dialog.xml +++ b/app/src/main/res/layout/edit_bookmark_databaseview_dialog.xml @@ -1,7 +1,7 @@ - + - - + - - + - - + - + - - + - - + - - + \ No newline at end of file diff --git a/app/src/main/res/layout/edit_bookmark_folder_databaseview_dialog.xml b/app/src/main/res/layout/edit_bookmark_folder_databaseview_dialog.xml index 4b9cec3d..bb59f8b9 100644 --- a/app/src/main/res/layout/edit_bookmark_folder_databaseview_dialog.xml +++ b/app/src/main/res/layout/edit_bookmark_folder_databaseview_dialog.xml @@ -1,7 +1,7 @@ - + - - + - + - - + - + + android:inputType="text" + tools:ignore="Autofill" /> + android:text="@string/zero_of_zero" /> -true to make the status bar a transparent, darkened overlay. --> + - - + - - - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/http_authentication_dialog.xml b/app/src/main/res/layout/http_authentication_dialog.xml index df262c55..52e543d1 100644 --- a/app/src/main/res/layout/http_authentication_dialog.xml +++ b/app/src/main/res/layout/http_authentication_dialog.xml @@ -1,7 +1,7 @@ - + - - + - - + - - + \ No newline at end of file diff --git a/app/src/main/res/layout/import_export_coordinatorlayout.xml b/app/src/main/res/layout/import_export_coordinatorlayout.xml index c7dbc810..a38850aa 100644 --- a/app/src/main/res/layout/import_export_coordinatorlayout.xml +++ b/app/src/main/res/layout/import_export_coordinatorlayout.xml @@ -1,7 +1,7 @@ - - - - + - - - - + - + - - - - +