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'
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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.
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.
// 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.
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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);
}
}
- 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;
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- `android:layout_weight="1"` sets the `RelativeLayout` to fill the rest of the screen because it is encapsulated in a `LinearLayout` with `android:orientation="vertical"`.-->
<!-- `android:background=@color/gray_900` sets the background color that is displayed when a website is loading in night mode. -->
<RelativeLayout
- android:id="@+id/main_webview_relativelayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
ads:adUnitId="@string/ad_unit_id" >
</com.google.android.gms.ads.AdView>
- <android.support.v4.widget.SwipeRefreshLayout
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true" />
- </android.support.v4.widget.SwipeRefreshLayout>
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</RelativeLayout>
\ No newline at end of file
<!-- The file provider is required to encrypt files with OpenKeychain. -->
<provider
- android:name="android.support.v4.content.FileProvider"
+ android:name="androidx.core.content.FileProvider"
android:authorities="@string/file_provider"
android:exported="false"
android:grantUriPermissions="true" >
<p>Privacy Browser ist veröffentlicht unter der <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ Lizenz</a>. The full text of the license is below.
The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
- <h3>Block Lists</h3>
+ <h3>Blocklists</h3>
<p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
<p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
<h3>Libraries</h3>
- <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>Privacy Browser ist veröffentlicht unter der <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ Lizenz</a>. The full text of the license is below.
The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
- <h3>Block Lists</h3>
+ <h3>Blocklists</h3>
<p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
<p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
<h3>Libraries</h3>
- <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>Privacy Browser is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>. The full text of the license is below.
The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
- <h3>Block Lists</h3>
+ <h3>Blocklists</h3>
<p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
<p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
<h3>Libraries</h3>
- <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>Privacy Browser is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>. The full text of the license is below.
The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
- <h3>Block Lists</h3>
+ <h3>Blocklists</h3>
<p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
<p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
<h3>Libraries</h3>
- <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>Más información sobre las listas de bloqueo puede encontrarse en la <a href="https://easylist.to/">página web de EasyList</a>.</p>
<h3>Librerías</h3>
- <p>Navegador privado está construido con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">librería de soporte de android</a>,
- que se libera bajo la <a href="https://www.apache.org/licenses/LICENSE-2.0">Licencia Apache 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>El sabor o versión libre de Navegador Privado está construido con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">anuncios de Firebase</a>,
que se libera bajo la <a href="https://developer.android.com/studio/terms">Licencia del Android Software Development Kit</a>.</p>
<p>Más información sobre las listas de bloqueo puede encontrarse en la <a href="https://easylist.to/">página web de EasyList</a>.</p>
<h3>Librerías</h3>
- <p>Navegador privado está construido con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">librería de soporte de android</a>,
- que se libera bajo la <a href="https://www.apache.org/licenses/LICENSE-2.0">Licencia Apache 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>El sabor o versión libre de Navegador Privado está construido con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">anuncios de Firebase</a>,
que se libera bajo la <a href="https://developer.android.com/studio/terms">Licencia del Android Software Development Kit</a>.</p>
E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini <a href="https://www.gnu.org/licenses/translations.html">qui</a> riportati.
Il codice sorgente è disponibile su <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
- <h3>Block List</h3>
+ <h3>Blocklist</h3>
<p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> e <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
sono <a href="https://easylist.to/pages/licence.html">sotto doppia licenza</a> con le licenze <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
e <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a>. Privacy Browser le incorpora utilizzando l'opzione GPLv3+.</p>
<p>E' possibile reperire maggiori informazioni sulle block list sul <a href="https://easylist.to/">sito web EasyList</a>.</p>
<h3>Librerie</h3>
- <p>Privacy Browser è sviluppato con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- che è rilasciata con <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>La versione gratuita di Privacy Browser è compilata con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
che è rilasciato sotto la <a href="https://developer.android.com/studio/terms">Licenza Android Software Development Kit</a>.</p>
E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini <a href="https://www.gnu.org/licenses/translations.html">qui</a> riportati.
Il codice sorgente è disponibile su <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
- <h3>Block List</h3>
+ <h3>Blocklist</h3>
<p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> e <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
sono <a href="https://easylist.to/pages/licence.html">sotto doppia licenza</a> con le licenze <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
e <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a>. Privacy Browser le incorpora utilizzando l'opzione GPLv3+.</p>
<p>E' possibile reperire maggiori informazioni sulle block list sul <a href="https://easylist.to/">sito web EasyList</a>.</p>
<h3>Librerie</h3>
- <p>Privacy Browser è sviluppato con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- che è rilasciata con <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>La versione gratuita di Privacy Browser è compilata con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
che è rilasciato sotto la <a href="https://developer.android.com/studio/terms">Licenza Android Software Development Kit</a>.</p>
<p>Более подробную информацию о списках блокировки можно найти на <a href="https://easylist.to/">веб-сайте EasyList</a>.</p>
<h3>Библиотеки</h3>
- <p>Privacy Browser создан с использованием <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- которая выпущена под <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>Бесплатный вариант Privacy Browser создан с помощью <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
выпущенной по лицензии <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>Более подробную информацию о списках блокировки можно найти на <a href="https://easylist.to/">веб-сайте EasyList</a>.</p>
<h3>Библиотеки</h3>
- <p>Privacy Browser создан с использованием <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- которая выпущена под <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>Бесплатный вариант Privacy Browser создан с помощью <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
выпущенной по лицензии <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
<h3>Libraries</h3>
- <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
<p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
<h3>Libraries</h3>
- <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
- which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+ <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+ and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+ which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
<p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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);
}
private class aboutPagerAdapter extends FragmentPagerAdapter {
- private aboutPagerAdapter(FragmentManager fm) {
- super(fm);
+ private aboutPagerAdapter(FragmentManager fragmentManager) {
+ // Run the default commands.
+ super(fragmentManager);
}
@Override
package com.stoutner.privacybrowser.activities;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
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;
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;
// 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;
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;
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;
// 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) {
// 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));
});
}
}
@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);
}
@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);
}
@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);
}
@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);
}
@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);
package com.stoutner.privacybrowser.activities;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
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;
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;
// 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);
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));
}
});
// 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) {
}
@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);
}
@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);
package com.stoutner.privacybrowser.activities;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
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;
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;
// `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;
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);
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));
});
}
// 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.
// 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);
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.
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);
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);
@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.
// 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);
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();
// 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) {
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();
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;
// 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) {
// 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);
}
@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();
// 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();
}
}
// 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.
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
// 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);
}
private class guidePagerAdapter extends FragmentPagerAdapter {
- private guidePagerAdapter(FragmentManager fm) {
- super(fm);
+ private guidePagerAdapter(FragmentManager fragmentManager) {
+ // Run the default commands.
+ super(fragmentManager);
}
@Override
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;
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;
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);
// 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";
}
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) {
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()) {
// 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;
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.
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;
// 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);
}
@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);
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;
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;
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;
// `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;
// `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;
// `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;
// `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;
// 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));
// 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);
// 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.
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")) {
* 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) {
}
}
} 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")) {
// 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.
});
// 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);
});
// Implement swipe to refresh.
- swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
swipeRefreshLayout.setOnRefreshListener(() -> mainWebView.reload());
// Set the swipe to refresh color according to the theme.
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.
}
});
- // 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);
* 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);
* 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);
}
}
} 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);
// 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.
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));
}
}
});
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.
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));
}
}
});
// 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);
// 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);
}
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);
* 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);
}
}
@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);
// 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);
}
}
// 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();
// 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());
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;
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);
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;
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:
// 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:
// Clear `customHeaders`.
customHeaders.clear();
- // Detach all views from `mainWebViewRelativeLayout`.
- mainWebViewRelativeLayout.removeAllViews();
-
// Destroy the internal state of `mainWebView`.
mainWebView.destroy();
break;
}
+ // Get a handle for the drawer layout.
+ DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+
// Close the navigation drawer.
drawerLayout.closeDrawer(GravityCompat.START);
return true;
@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
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;
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;
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;
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;
}
@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);
}
@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);
}
@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();
@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.
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.
}
@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`.
}
@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`.
}
@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);
}
@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);
}
@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);
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
// 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);
// 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);
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.
* 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);
// 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);
// 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);
}
}
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);
if (mainMenu != null) {
updatePrivacyIcons(true);
}
+
+ // TODO.
+ swipeRefreshLayout.setEnabled(false);
}
// Reload the website if returning from the Domains activity.
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`.
// 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.
// 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.
!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");
}
}
}
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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;
// 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();
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
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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;
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;
// 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);
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.definitions.History;
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
+++ /dev/null
-package com.stoutner.privacybrowser.definitions;
-
-/*
- * Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
- */
-
-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
/*
- * Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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()`.
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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()`
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;
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`.
/*
- * Copyright © 2015-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2015-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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()`.
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.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
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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.
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
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;
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");
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;
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 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;
// 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
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;
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;
// 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) {
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;
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;
// 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) {
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;
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) {
/*
- * Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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;
public interface HttpAuthenticationListener {
void onHttpAuthenticationCancel();
- void onHttpAuthenticationProceed(AppCompatDialogFragment dialogFragment);
+ void onHttpAuthenticationProceed(DialogFragment dialogFragment);
}
public void onAttach(Context context) {
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;
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;
import java.io.ByteArrayOutputStream;
-public class MoveToFolderDialog extends AppCompatDialogFragment {
+public class MoveToFolderDialog extends DialogFragment {
// Instantiate the class variables.
private MoveToFolderListener moveToFolderListener;
private BookmarksDatabaseHelper bookmarksDatabaseHelper;
// 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) {
@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.
addSubfoldersToExceptFolders(subfolderName);
}
}
-}
+}
\ No newline at end of file
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;
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;
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;
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) {
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;
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;
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;
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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;
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;
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<History> historyArrayList = new ArrayList<>();
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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);
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;
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;
// `@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();
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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;
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;
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;
/*
- * Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
// 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();
// 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();
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
/*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
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;
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 = {
--- /dev/null
+/*
+ * Copyright © 2019 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
+ */
+
+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
--- /dev/null
+/*
+ * Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
+ */
+
+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
android:dividerHeight="0dp" />
</LinearLayout>
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.FloatingActionButton
android:id="@+id/launch_bookmarks_activity_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="155dp" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.FloatingActionButton
android:id="@+id/create_bookmark_folder_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="85dp" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.FloatingActionButton
android:id="@+id/create_bookmark_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
<!-- `android:choiceMode="singleChoice"` allows a selected domain to be highlighted.-->
-<tools:ListView
+<ListView
android:id="@+id/domains_listview"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/about_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- We need to set `android:background="?attr/colorPrimaryDark"` here or any space to the right of the `TabLayout` on large devices will be the theme background color. -->
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/about_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark" >
<!-- `android:theme="?attr/appBarTextTheme"` sets the color of the text and icons in the `AppBar`. -->
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/about_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="?attr/appBarTextTheme" />
<!-- For some reason `tabIndicatorColor` does not pull from the style unless specified explicitly here. -->
- <android.support.design.widget.TabLayout
+ <com.google.android.material.tabs.TabLayout
android:id="@+id/about_tablayout"
xmlns:android.support.design="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android.support.design:tabMode="scrollable"
android.support.design:tabIndicatorColor="?attr/tabIndicatorColor"
android:theme="?attr/tabLayoutTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<!-- `android:layout_weight="1"` makes `about_viewpager` fill the rest of the screen. -->
- <android.support.v4.view.ViewPager
+ <androidx.viewpager.widget.ViewPager
android:id="@+id/about_viewpager"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1" />
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:layout_width="match_parent"
android:orientation="vertical" >
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo" sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/domain_name_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/domain_name_already_exists_textview"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/bookmarks_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/bookmarks_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/bookmarks_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark"
android:theme="?attr/appBarTextTheme"
app:popupTheme="?attr/popupsTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<!-- `android:choiceMode="multipleChoiceModal"` allows the contextual action menu to select more than one item at a time.
`android:dividerHeight` must be at least `1dp` or the `ListView` is inconsistent in calculating how many bookmarks are displayed. -->
android:dividerHeight="1dp" />
</LinearLayout>
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/create_bookmark_folder_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginBottom="85dp"
android:src="?attr/addFolderIcon" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/create_bookmark_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="?attr/addBookmarkIcon" />
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>`
to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/bookmarks_databaseview_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/bookmarks_databaseview_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/bookmarks_databaseview_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark"
android:theme="?attr/appBarTextTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<!-- `android:choiceMode="multipleChoiceModal"` allows the contextual action menu to select more than one item at a time. -->
<ListView
android:layout_width="match_parent"
android:choiceMode="multipleChoiceModal" />
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017, 2019 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:dividerHeight="0dp" />
</LinearLayout>
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/launch_bookmarks_activity_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="155dp" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/create_bookmark_folder_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="85dp" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/create_bookmark_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:layout_width="match_parent"
android:orientation="vertical" >
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/create_bookmark_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="6dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <EditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/create_bookmark_url_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/bookmark_url"
android:imeOptions="actionGo"
android:inputType="textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
</RadioGroup>
</LinearLayout>
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="6dp"
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a "go" key instead of a "new line" key.
`android:inputType="textUri"` disables spell check in the EditText. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/create_folder_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/folder_name"
android:imeOptions="actionGo"
android:inputType="textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_height="wrap_content"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2015-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2015-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="16dp"
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.
`android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/shortcut_name_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
\ No newline at end of file
android:tint="?attr/domainSettingsIconTintColor"
tools:ignore="contentDescription" />
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginStart="6dp" >
<!-- `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/domain_settings_name_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/domain_name"
android:inputType="textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<TextView
</LinearLayout>
<!-- Saved Certificate -->
- <android.support.v7.widget.CardView
+ <androidx.cardview.widget.CardView
android:id="@+id/saved_ssl_certificate_cardview"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_width="match_parent" />
</LinearLayout>
</LinearLayout>
- </android.support.v7.widget.CardView>
+ </androidx.cardview.widget.CardView>
<!-- Current Website Certificate -->
- <android.support.v7.widget.CardView
+ <androidx.cardview.widget.CardView
android:id="@+id/current_website_certificate_cardview"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_width="match_parent" />
</LinearLayout>
</LinearLayout>
- </android.support.v7.widget.CardView>
+ </androidx.cardview.widget.CardView>
<!-- Load An Encrypted Website Instructions. -->
<TextView
</LinearLayout>
<!-- Saved IP Addresses -->
- <android.support.v7.widget.CardView
+ <androidx.cardview.widget.CardView
android:id="@+id/saved_ip_addresses_cardview"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginStart="32dp"
android:textColor="?attr/aboutText" />
</LinearLayout>
- </android.support.v7.widget.CardView>
+ </androidx.cardview.widget.CardView>
- <android.support.v7.widget.CardView
+ <androidx.cardview.widget.CardView
android:id="@+id/current_ip_addresses_cardview"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginStart="32dp"
android:textColor="?attr/aboutText" />
</LinearLayout>
- </android.support.v7.widget.CardView>
+ </androidx.cardview.widget.CardView>
</LinearLayout>
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
You should have received a copy of the GNU General Public License
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
-<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar. When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
+ When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/domains_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/domains_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark"
android:theme="?attr/appBarTextTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/domains_fragments" />
</LinearLayout>
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_domain_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="?attr/addIcon" />
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:padding="6dp">
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key.
- `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/download_file_name"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/file_name"
android:imeOptions="actionGo"
android:inputType="textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/download_file_size"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:padding="6dp">
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key.
- `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/download_image_name"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/image_name"
android:imeOptions="actionGo"
android:inputType="textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
</RadioGroup>
</LinearLayout>
- <!-- Bookmark name. `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- Bookmark name. The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_bookmark_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
- <!-- URL. `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- URL. The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="6dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_bookmark_url_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<!-- Folder. -->
<LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
</RadioGroup>
</LinearLayout>
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_bookmark_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="6dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <EditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_bookmark_url_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
</RadioGroup>
</LinearLayout>
- <!-- Folder name. `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- Folder name. The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_marginEnd="4dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_folder_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<!-- Folder. -->
<LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
</RadioGroup>
</LinearLayout>
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="6dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp" >
- <!-- `android:imeOptions="actionGo"` sets the keyboard to have a "go" key instead of a "new line" key.
- `android:inputType="textUri"` disables spell check in the EditText. -->
- <android.support.design.widget.TextInputEditText
+ <!-- `android:imeOptions="actionGo"` sets the keyboard to have a "go" key instead of a "new line" key. `android:inputType="textUri"` disables spell check in the EditText. -->
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_folder_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_height="wrap_content"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- `LinearLayout` is initially `visibility="gone"` so the `url_app_bar` is visible. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/find_on_page_linearlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/find_on_page"
android:lines="1"
android:imeOptions="actionDone"
- android:inputType="text" />
+ android:inputType="text"
+ tools:ignore="Autofill" />
<TextView
android:id="@+id/find_on_page_count_textview"
android:layout_width="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
- android:text="@string/zero_of_zero"
- />
+ android:text="@string/zero_of_zero" />
<ImageView
android:id="@+id/find_previous"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
<!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
- When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
- to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item> to make the status bar a transparent, darkened overlay. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/guide_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical" >
- <!-- We need to set `android:background="?attr/colorPrimaryDark"` here or any space to the right of the `TabLayout` on large devices will be the theme background color. -->
- <android.support.design.widget.AppBarLayout
+ <!-- `android:background="?attr/colorPrimaryDark"` needs to be set here or any space to the right of the `TabLayout` on large devices will be the theme background color. -->
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/guide_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark" >
<!-- `android:theme="?attr/appBarTextTheme"` sets the color of the text and icons in the `AppBar`. -->
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/guide_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="?attr/appBarTextTheme" />
<!-- For some reason `tabIndicatorColor` does not pull from the style unless specified explicitly here. -->
- <android.support.design.widget.TabLayout
+ <com.google.android.material.tabs.TabLayout
android:id="@+id/guide_tablayout"
xmlns:android.support.design="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android.support.design:tabMode="scrollable"
android.support.design:tabIndicatorColor="?attr/tabIndicatorColor"
android:theme="?attr/tabLayoutTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<!-- `android:layout_weight="1"` makes `about_viewpager` fill the rest of the screen. -->
- <android.support.v4.view.ViewPager
+ <androidx.viewpager.widget.ViewPager
android:id="@+id/guide_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp" />
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="6dp" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. `android:inputType="textUri"` disables spell check in the `EditText`. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/http_authentication_username"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:imeOptions="actionGo"
android:inputType="textUri"
android:selectAllOnFocus="true" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. -->
- <EditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/http_authentication_password"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/password"
android:imeOptions="actionGo"
android:inputType="textPassword" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/import_export_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/import_export_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/import_export_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark"
android:theme="?attr/appBarTextTheme"
app:popupTheme="?attr/popupsTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- The encryption card. -->
- <android.support.v7.widget.CardView
+ <androidx.cardview.widget.CardView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal" />
<!-- The encryption password. -->
- <android.support.design.widget.TextInputLayout
+ <com.google.android.material.textfield.TextInputLayout
android:id="@+id/password_encryption_textinputlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:passwordToggleEnabled="true" >
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_encryption_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/password"
android:inputType="textPassword"/>
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<!-- KitKat password encryption message. -->
<TextView
android:textColor="?android:textColorPrimary"
android:textAlignment="center" />
</LinearLayout>
- </android.support.v7.widget.CardView>
+ </androidx.cardview.widget.CardView>
<!-- The file location card. -->
- <android.support.v7.widget.CardView
+ <androidx.cardview.widget.CardView
android:id="@+id/file_location_cardview"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="10dp">
<!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1" >
<!-- `android:inputType="textUri" disables spell check and places an `/` on the main keyboard. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/file_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/file_name"
android:inputType="textMultiLine|textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/browse_button"
app:backgroundTint="?attr/buttonBackgroundColorSelector"
android:textColor="?attr/buttonTextColorSelector" />
</LinearLayout>
- </android.support.v7.widget.CardView>
+ </androidx.cardview.widget.CardView>
<TextView
android:id="@+id/import_export_storage_permission_textview"
</LinearLayout>
</ScrollView>
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/logcat_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/logcat_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/logcat_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark"
android:theme="?attr/appBarTextTheme"
app:popupTheme="?attr/popupsTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
- <android.support.v4.widget.SwipeRefreshLayout
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/logcat_swiperefreshlayout"
android:layout_height="match_parent"
android:layout_width="match_parent" >
android:layout_margin="10dp"
android:textIsSelectable="true" />
</ScrollView>
- </android.support.v4.widget.SwipeRefreshLayout>
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2015-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2015-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>>.
You should have received a copy of the GNU General Public License
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
-<android.support.v4.widget.DrawerLayout
+<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawerlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent" >
- <!-- `android:fitsSystemWindows="true"` moves `root_coordinatorlayout` below the system status bar. When it is specified, the theme should include `<item name="android:windowTranslucentStatus">true</item>`.
- Setting the CoordinatorLayout to be `focusableInTouchMode` prevents the URL text box from stealing focus on launch and opening the keyboard.
- `android:background` sets the background color of the status bar, which is then overlaid with a scrim. -->
- <android.support.design.widget.CoordinatorLayout
- android:id="@+id/root_coordinatorlayout"
+ <!-- `android:fitsSystemWindows="true"` moves the toolbar below the system status bar. When it is specified, the theme should include `<item name="android:windowTranslucentStatus">true</item>`.
+ Setting the CoordinatorLayout to be `focusableInTouchMode` prevents the URL text box from stealing focus on launch and opening the keyboard. -->
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
+ android:id="@+id/coordinatorlayout"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.stoutner.privacybrowser.activities.MainWebViewActivity"
android:layout_height="match_parent"
android:layout_width="match_parent"
- android:fitsSystemWindows="true"
android:focusable="true"
android:focusableInTouchMode="true"
- android:background="?attr/mainStatusBarBackground" >
+ android:fitsSystemWindows="true" >
- <!-- The purpose of the `LinearLayout` is to place the included `main_webview` below `app_bar_layout`. -->
- <LinearLayout
- android:layout_height="match_parent"
+ <!-- The `AppBarLayout` theme has to be defined here because the activity uses a `NoActionBar` theme. -->
+ <com.google.android.material.appbar.AppBarLayout
+ android:id="@+id/app_bar_layout"
+ android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:orientation="vertical" >
+ android:theme="@style/PrivacyBrowserAppBarLight" >
- <!-- The `AppBarLayout` theme has to be defined here because the activity uses a `NoActionBar` theme. -->
- <android.support.design.widget.AppBarLayout
- android:id="@+id/app_bar_layout"
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:theme="@style/PrivacyBrowserAppBarLight" >
+ app:layout_scrollFlags="scroll|enterAlways|snap" />
+
+ <!-- The `FrameLayout` allows `appBar` and `find_on_page_app_bar` to occupy the same space. -->
+ <!-- <FrameLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent" >
- <!-- The `FrameLayout` allows `appBar` and `find_on_page_app_bar` to occupy the same space. -->
- <FrameLayout
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/app_bar"
android:layout_height="wrap_content"
- android:layout_width="match_parent" >
-
- <android.support.v7.widget.Toolbar
- android:id="@+id/app_bar"
- android:layout_height="wrap_content"
- android:layout_width="match_parent" />
-
- <!-- `android:max` changes the maximum `ProgressBar` value from 10000 to 100 to match progress percentage.
- `android:layout_height="2dp"` works best for API >= 23, but `3dp` is required for visibility on API <= 22.
- `tools:ignore="UnusedAttribute"` removes the lint warning about `progressTint` and `progressBackgroundTint` not applying to API < 21. -->
- <ProgressBar
- android:id="@+id/progress_bar"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_height="3dp"
- android:layout_width="match_parent"
- android:layout_gravity="bottom"
- android:max="100"
- android:progressTint="?attr/progressTintColor"
- android:progressBackgroundTint="@color/transparent"
- android:visibility="gone"
- tools:ignore="UnusedAttribute" />
-
- <!-- Include the Find on Page search bar. -->
- <include layout="@layout/find_on_page_app_bar" />
- </FrameLayout>
- </android.support.design.widget.AppBarLayout>
-
- <!-- Include the main `WebView`. -->
- <include layout="@layout/main_webview" />
- </LinearLayout>
+ android:layout_width="match_parent"
+ app:layout_scrollFlags="scroll|enterAlways|snap" /> -->
+
+ <!-- `android:max` changes the maximum `ProgressBar` value from 10000 to 100 to match progress percentage.
+ `android:layout_height="2dp"` works best for API >= 23, but `3dp` is required for visibility on API <= 22.
+ `tools:ignore="UnusedAttribute"` removes the lint warning about `progressTint` and `progressBackgroundTint` not applying to API < 21. -->
+ <!-- <ProgressBar
+ android:id="@+id/progress_bar"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_height="3dp"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom"
+ android:max="100"
+ android:progressTint="?attr/progressTintColor"
+ android:progressBackgroundTint="@color/transparent"
+ android:visibility="gone"
+ tools:ignore="UnusedAttribute" /> -->
+
+ <!-- Include the Find on Page search bar. -->
+ <!-- <include layout="@layout/find_on_page_app_bar" />
+ </FrameLayout> -->
+ </com.google.android.material.appbar.AppBarLayout>
+
+
+ <com.stoutner.privacybrowser.views.NestedScrollWebView
+ android:id="@+id/main_webview"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+
+ <TextView
+ android:id="@+id/adview"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:visibility="gone" />
+
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+ android:id="@+id/swiperefreshlayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+
+ <ProgressBar
+ android:id="@+id/progress_bar"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_height="3dp"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom"
+ android:max="100"
+ android:progressTint="?attr/progressTintColor"
+ android:progressBackgroundTint="@color/transparent"
+ android:visibility="gone"
+ tools:ignore="UnusedAttribute" />
+ <include layout="@layout/find_on_page_app_bar" />
+
+ <!-- Include the main `WebView`. -->
+ <!-- <include layout="@layout/main_webview" /> -->
<!-- `full_screen_video_framelayout` is used to display full screen videos. It is initially `android:visibility="gone"` to hide it from view. -->
<FrameLayout
android:layout_width="match_parent"
android:visibility="gone"
android:background="@color/black" />
- </android.support.design.widget.CoordinatorLayout>
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- The navigation drawer. -->
- <android.support.design.widget.NavigationView
+ <com.google.android.material.navigation.NavigationView
android:id="@+id/navigationview"
android:layout_height="match_parent"
android:layout_width="wrap_content"
<!-- Include the bookmarks drawer. -->
<include layout="@layout/bookmarks_drawer" />
-</android.support.v4.widget.DrawerLayout>
\ No newline at end of file
+</androidx.drawerlayout.widget.DrawerLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- `android:layout_weight="1"` sets the `RelativeLayout` to fill the rest of the screen because it is encapsulated in a `LinearLayout` with `android:orientation="vertical"`. -->
<!-- `android:background=@color/gray_900` sets the background color that is displayed when a website is loading in night mode. -->
<RelativeLayout
- android:id="@+id/main_webview_relativelayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:background="@color/gray_900"
- tools:context="com.stoutner.privacybrowser.activities.MainWebViewActivity" >
+ tools:context="com.stoutner.privacybrowser.activities.MainWebViewActivity"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- This `TextView` has an id of `adView` so that the ad commands (which do nothing in the standard flavor) don't produce errors. -->
<TextView
android:layout_width="wrap_content"
android:visibility="gone" />
- <android.support.v4.widget.SwipeRefreshLayout
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Google does not currently want to support hiding the AppBar on scroll for a WebView child with the Support Toolbar. https://code.google.com/p/android/issues/detail?id=200394 -->
- <WebView
+ <com.stoutner.privacybrowser.views.NestedScrollWebView
android:id="@+id/main_webview"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="true"
- android:focusableInTouchMode="true"/>
- </android.support.v4.widget.SwipeRefreshLayout>
+ android:focusableInTouchMode="true"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</RelativeLayout>
\ No newline at end of file
android:layout_width="wrap_content"
android:orientation="vertical">
- <android.support.design.widget.TabLayout
+ <com.google.android.material.tabs.TabLayout
android:id="@+id/pinned_ssl_certificate_mismatch_tablayout"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="wrap_content" >
- <com.stoutner.privacybrowser.definitions.WrapVerticalContentViewPager
+ <com.stoutner.privacybrowser.views.WrapVerticalContentViewPager
android:id="@+id/pinned_ssl_certificate_mismatch_viewpager"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/requests_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical" >
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/requests_appbarlayout"
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/requests_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimaryDark"
android:theme="?attr/appBarTextTheme"
app:popupTheme="?attr/popupsTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<!-- `android:dividerHeight` must be at least `1dp` or the `ListView` is inconsistent in calculating how many bookmarks are displayed. -->
<ListView
android:divider="@color/transparent"
android:dividerHeight="1dp" />
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
android:layout_width="match_parent"
android:orientation="horizontal" >
- <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
- <android.support.design.widget.TextInputLayout
+ <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1" >
<!-- `android:inputType="textUri" disables spell check and places an `/` on the main keyboard. -->
- <android.support.design.widget.TextInputEditText
+ <com.google.android.material.textfield.TextInputEditText
android:id="@+id/file_name_edittext"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="@string/file_name"
android:inputType="textMultiLine|textUri" />
- </android.support.design.widget.TextInputLayout>
+ </com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/browse_button"
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2015-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2015-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:hint="@string/url"
android:imeOptions="actionGo"
android:inputType="textUri"
- android:selectAllOnFocus="true" />
+ android:selectAllOnFocus="true"
+ tools:ignore="Autofill" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar. When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay.
Setting the layout root to be `focusableInTouchMode` prevents the URL toolbar from stealing focus on launch and opening the keyboard. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/view_source_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" >
<!-- The `AppBarLayout` theme has to be defined here because the activity uses a `NoActionBar` theme. -->
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/PrivacyBrowserAppBarLight" >
android:layout_height="wrap_content"
android:layout_width="match_parent" >
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/view_source_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
- <!-- Android automatically uses a different, skinnier drawable with padding for indeterminate horizontal progress bars in API >= 21. They make this very difficult to override. https://redmine.stoutner.com/issues/241
- `tools:ignore="UnusedAttribute"` removes the lint warning about `progressTint` and `progressBackgroundTint` not applying to API < 21. -->
+ <!-- Android automatically uses a different, skinnier drawable with padding for indeterminate horizontal progress bars in API >= 21.
+ They make this very difficult to override. https://redmine.stoutner.com/issues/241
+ `tools:ignore="UnusedAttribute"` removes the lint warning about `progressTint` and `progressBackgroundTint` not applying to API < 21. -->
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:visibility="gone"
tools:ignore="UnusedAttribute" />
</FrameLayout>
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
- <android.support.v4.widget.SwipeRefreshLayout
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/view_source_swiperefreshlayout"
android:layout_height="match_parent"
android:layout_width="match_parent">
android:textIsSelectable="true" />
</LinearLayout>
</ScrollView>
- </android.support.v4.widget.SwipeRefreshLayout>
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<string name="load_an_encrypted_website">Zuerst verschlüsselte Webseite laden...</string>
<!-- Import/Export. -->
- <string name="privacy_browser_settings_pbs">Privacy Browser Einstellungen.pbs</string>
+ <string name="settings_pbs">Einstellungen.pbs</string>
<!-- Guide. -->
<string name="overview">Übersicht</string>
<string name="downloads">Descargas</string>
<string name="settings">Configuración</string>
<string name="import_export">Importar/Exportar</string>
+ <string name="logcat">Logcat</string>
<string name="guide">Guía</string>
<string name="about">Acerca de</string>
<string name="clear_and_exit">Borrar y salir</string>
<string name="kitkat_password_encryption_message">El cifrado de contraseñas no funciona en Android KitKat.</string>
<string name="openkeychain_required">El cifrado OpenPGP requiere que esté instalado OpenKeychain.</string>
<string name="openkeychain_import_instructions">El archivo sin cifrar tendrá que ser importado en un paso separado después de ser descifrado.</string>
- <string name="privacy_browser_settings_pbs">Configuración de Navegador Privado.pbs</string>
+ <string name="settings_pbs">Configuración.pbs</string>
<string name="file_location">Ubicación del archivo</string>
<string name="browse">Navegar</string>
<string name="export">Exportar</string>
Si se deniega, los directorios de la aplicación pueden seguir utilizándose.</string>
<string name="storage_permission_explanation">El acceso a los archivos en directorios públicos requiere el permiso de almacenamiento.
De lo contrario, sólo funcionarán los directorios de aplicaciones.</string>
+ <string name="cannot_use_location">Esta ubicación no se puede utilizar porque no se ha concedido el permiso de almacenamiento.</string>
+
+ <!-- Logcat. -->
+ <string name="copy">Copiar</string>
+ <string name="logcat_copied">Logcat copiado.</string>
+ <string name="clear">Borrar</string>
+ <string name="save_logcat">Guardar logcat</string>
+ <string name="privacy_browser_logcat_txt">Navegador Privado Logcat.txt</string>
+ <string name="file_saved_successfully">Archivo guardado con éxito.</string>
+ <string name="save_failed">Error al guardar:</string>
<!-- Guide. -->
<string name="overview">Visión general</string>
<string name="downloads">Download</string>
<string name="settings">Impostazioni</string>
<string name="import_export">Importa/Esporta</string>
+ <string name="logcat">Logcat</string>
<string name="guide">Guida</string>
<string name="about">Informazioni</string>
<string name="clear_and_exit">Elimina dati ed esci</string>
<string name="kitkat_password_encryption_message">La cifratura delle Password non funziona su Android KitKat.</string>
<string name="openkeychain_required">La cifratura OpenPGP richiede l\'installazione di OpenKeychain.</string>
<string name="openkeychain_import_instructions">Il file non cifrato deve essere importato in un secondo momento dopo che è stato decriptato.</string>
+ <string name="settings_pbs">Impostazioni.pbs</string>
<string name="file_location">Posizione del File</string>
<string name="browse">Sfoglia</string>
<string name="export">Esporta</string>
Se questo permesso è negato possono comunque essere utilizzate le cartelle dell\'applicazione.</string>
<string name="storage_permission_explanation">L\'accesso ai file posti in cartelle pubbliche richiede il permesso di accesso alla memoria,
altrimenti saranno accessibili solo le cartelle dell\'applicazione.</string>
+ <string name="cannot_use_location">Questa posizione non può essere utilizzata perché non è stato concesso il permesso di scrittura in memoria.</string>
+
+ <!-- Logcat. -->
+ <string name="copy">Copia</string>
+ <string name="logcat_copied">Logcat copiato.</string>
+ <string name="clear">Cancella</string>
+ <string name="save_logcat">Salva il log</string>
+ <string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
+ <string name="file_saved_successfully">File salvato.</string>
+ <string name="save_failed">Errore di salvataggio:</string>
<!-- Guide. -->
<string name="overview">Descrizione</string>
<string name="downloads">Загрузки</string>
<string name="settings">Настройки</string>
<string name="import_export">Импорт/Экспорт</string>
+ <string name="logcat">Logcat</string>
<string name="guide">Руководство</string>
<string name="about">О Privacy Browser</string>
<string name="clear_and_exit">Очистить и выйти</string>
<string name="kitkat_password_encryption_message">Шифрование паролем не работает на Android KitKat.</string>
<string name="openkeychain_required">Для использования шифрования OpenPGP необходимо приложение OpenKeychain.</string>
<string name="openkeychain_import_instructions">Незашифрованный файл должен быть импортирован на отдельном шаге после его дешифрования.</string>
- <string name="privacy_browser_settings_pbs">Настройки Privacy Browser.pbs</string>
+ <string name="settings_pbs">Настройки.pbs</string>
<string name="file_location">Расположение файла</string>
<string name="browse">Обзор</string>
<string name="export">Экспорт</string>
<string name="storage_permission">Доступ к хранилищу</string>
<string name="storage_permission_message">Privacy Browser необходимо разрешение на доступ к внешним папкам. Если доступ предоставлен не будет, можно использовать локальную папку приложения.</string>
<string name="storage_permission_explanation">Для доступа к файлам во внешних папках требуется соответствующее разрешение. В противном случае будут работать только локальные папки.</string>
+ <string name="cannot_use_location">Это расположение использовано быть не может, поскольку разрешение на хранение предоставлено не было.</string>
+
+ <!-- Logcat. -->
+ <string name="copy">Копировать</string>
+ <string name="logcat_copied">Logcat скопирован.</string>
+ <string name="clear">Очистить</string>
+ <string name="save_logcat">Сохранить logcat</string>
+ <string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
+ <string name="file_saved_successfully">Файл успешно сохранен.</string>
+ <string name="save_failed">Сохранить не удалось:</string>
<!-- Guide. -->
<string name="overview">Обзор</string>
<string name="downloads">İndirilenler</string>
<string name="settings">Ayarlar</string>
<string name="import_export">İçeri Aktar/Dışarı Aktar</string>
+ <string name="logcat">Logcat</string>
<string name="guide">Rehber</string>
<string name="about">Hakkında</string>
<string name="clear_and_exit">Temizle ve Çık</string>
<string name="kitkat_password_encryption_message">Android KitKat sürümünde parola şifrelemesi çalışmaz.</string>
<string name="openkeychain_required">OpenPGP şifrelemesinin çalışması için OpenKeychain yüklü olmalıdır.</string>
<string name="openkeychain_import_instructions">Şifresi çözüldükten sonra, şifrelenmemiş dosya ayrı bir adımda içeri aktarılmak zorundadır.</string>
- <string name="privacy_browser_settings_pbs">Privacy Browser Ayarları.pbs</string>
+ <string name="settings_pbs">Ayarları.pbs</string>
<string name="file_location">Dosya Konumu</string>
<string name="browse">Gözat</string>
<string name="export">Dışarı aktar</string>
<string name="storage_permission">Depolama Alanı İzni</string>
<string name="storage_permission_message">Privacy Browser, genel dizinlere erişmek için depolama alanı iznine ihtiyaç duymaktadır. Reddedildiği takdirde, uygulamanın dizinleri hala kullanılabilir.</string>
<string name="storage_permission_explanation">Genel dizinlerdeki dosyalara erişim icin depolama alanı izni gerekmektedir. Aksi takdirde, sadece uygulamanın dizinleri çalışacaktır.</string>
+ <string name="cannot_use_location">Depolama izni verilmediğinden dolayı bu konum kullanılamaz.</string>
+
+ <!-- Logcat. -->
+ <string name="copy">Kopyala</string>
+ <string name="logcat_copied">Logcat kopyalandı.</string>
+ <string name="clear">Temizle</string>
+ <string name="save_logcat">Logcat\'i kaydet</string>
+ <string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
+ <string name="file_saved_successfully">Dosya başarıyla kaydedildi.</string>
+ <string name="save_failed">Kayıt başarısız:</string>
<!-- Guide. -->
<string name="overview">Genel Bakış</string>
<string name="kitkat_password_encryption_message">Password encryption does not work on Android KitKat.</string>
<string name="openkeychain_required">OpenPGP encryption requires that OpenKeychain be installed.</string>
<string name="openkeychain_import_instructions">The unencrypted file will have to be imported in a separate step after it is decrypted.</string>
- <string name="privacy_browser_settings_pbs">Privacy Browser Settings.pbs</string>
+ <string name="settings_pbs">Settings.pbs</string>
<string name="file_location">File Location</string>
<string name="browse">Browse</string>
<string name="export">Export</string>
/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
package com.stoutner.privacybrowser.dialogs;
-import android.app.DialogFragment;
+// The AndroidX dialog fragment must be used or an error is produced on API <=22.
+import androidx.fragment.app.DialogFragment;
public class AdConsentDialog extends DialogFragment {
// Do nothing because this is the standard flavor.
*/
package com.stoutner.privacybrowser.helpers;
-
-import android.app.FragmentManager;
import android.content.Context;
import android.view.View;
+import androidx.fragment.app.FragmentManager;
+
@SuppressWarnings("unused")
public class AdHelper {
public static void initializeAds(View view, Context applicationContext, FragmentManager fragmentManager, String googleAppId, String adUnitId) {
+# Copyright © 2019 Soren Stoutner <soren@stoutner.com>.
+#
+# This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
+
+
+
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+# org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
+# org.gradle.parallel=true
+
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+
+# Automatically convert third-party libraries to use AndroidX. This is necessary for Firebase Ads in the free flavor.
+android.enableJetifier=true
\ No newline at end of file