/*
- * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2020 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.Activity;
import android.content.Context;
import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.Display;
import android.view.View;
import android.widget.RelativeLayout;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;
+
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
public class AdHelper {
private static boolean initialized;
- public static void initializeAds(View view, Context applicationContext, FragmentManager fragmentManager, String googleAppId, String adUnitId) {
+ public static void initializeAds(View view, Context applicationContext, Activity activity, FragmentManager fragmentManager, String adUnitId) {
if (!initialized) { // This is the first run.
// Initialize mobile ads.
- MobileAds.initialize(applicationContext, googleAppId);
+ MobileAds.initialize(applicationContext);
// Initialize the bookmarks database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `AdConsentDatabaseHelper`.
AdConsentDatabaseHelper adConsentDatabaseHelper = new AdConsentDatabaseHelper(applicationContext, null, null, 0);
// Display the ad consent dialog if needed.
if (!adConsentGranted) { // Ad consent has not been granted.
- // Display the ad consent dialog.
+ // Instantiate the ad consent dialog.
DialogFragment adConsentDialogFragment = new AdConsentDialog();
+
+ // Display the ad consent dialog.
adConsentDialogFragment.show(fragmentManager, "Ad Consent");
} else { // Ad consent has been granted.
// Load an ad.
- loadAd(view, applicationContext, adUnitId);
+ loadAd(view, applicationContext, activity, adUnitId);
}
// Set the initialized variable to true so this section doesn't run again.
initialized = true;
} else { // Ads have previously been initialized.
// Load an ad.
- loadAd(view, applicationContext, adUnitId);
+ loadAd(view, applicationContext, activity, adUnitId);
}
}
- public static void loadAd(View view, Context applicationContext, String adUnitId) {
+ public static void loadAd(View view, Context applicationContext, Activity activity, String adUnitId) {
// Cast the generic view to an AdView.
AdView adView = (AdView) view;
// Save the layout parameters. They are used when programatically recreating the ad below.
RelativeLayout.LayoutParams adViewLayoutParameters = (RelativeLayout.LayoutParams) adView.getLayoutParams();
- // Remove the AdView.
+ // Get a handle for the ad view parent.
RelativeLayout adViewParentLayout = (RelativeLayout) adView.getParent();
+
+ // Remove the AdView.
adViewParentLayout.removeView(adView);
- // Setup the new AdView. This is necessary because the size of the banner ad can change on rotate.
+ // Create a new AdView. This is necessary because the size can change when the device is rotated.
adView = new AdView(applicationContext);
- adView.setAdSize(AdSize.SMART_BANNER);
+
+ // Set the ad unit ID.
adView.setAdUnitId(adUnitId);
+
+ // Set the view ID.
adView.setId(R.id.adview);
+
+ // Set the layout parameters.
adView.setLayoutParams(adViewLayoutParameters);
- // Display the new AdView.
+ // Add the new ad view to the parent layout.
adViewParentLayout.addView(adView);
- // Only request non-personalized ads. https://developers.google.com/ad-manager/mobile-ads-sdk/android/eu-consent#forward_consent_to_the_google_mobile_ads_sdk
+ // Get a handle for the display.
+ Display display = activity.getWindowManager().getDefaultDisplay();
+
+ // Initialize a display metrics.
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+
+ // Get the display metrics from the display.
+ display.getMetrics(displayMetrics);
+
+ // Get the width pixels and the density.
+ float widthPixels = displayMetrics.widthPixels;
+ float density = displayMetrics.density;
+
+ // Calculate the ad width.
+ int adWidth = (int) (widthPixels / density);
+
+ // Get the ad size. This line should be enabled once Firebase Ads is updated to 20.0.0.
+ AdSize adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(applicationContext, adWidth);
+
+ // Set the ad size on the adView.
+ adView.setAdSize(adSize);
+
+ // Create an ad settings bundle.
Bundle adSettingsBundle = new Bundle();
+
+ // Only request non-personalized ads. https://developers.google.com/ad-manager/mobile-ads-sdk/android/eu-consent#forward_consent_to_the_google_mobile_ads_sdk
adSettingsBundle.putString("npa", "1");
// Build the ad request.
adView.loadAd(adRequest);
}
+ // This method exists here for the sake of consistency with the following two methods.
public static void hideAd(View view) {
// Cast the generic view to an AdView.
AdView adView = (AdView) view;
adView.setVisibility(View.GONE);
}
+ // This method exists here so that the main WebView activity doesn't need to import `com.google.android.gms.ads.AdView`.
public static void pauseAd(View view) {
// Cast The generic view to an AdView.
AdView adView = (AdView) view;
adView.pause();
}
+ // This method exists here so that the main WebView activity doesn't need to import `com.google.android.gms.ads.AdView`.
public static void resumeAd(View view) {
// Cast the generic view to an AdView.
AdView adView = (AdView) view;
private String saveWebpageFilePath;
// Declare the class views.
+ private FrameLayout rootFrameLayout;
private DrawerLayout drawerLayout;
+ private RelativeLayout mainContentRelativeLayout;
private AppBarLayout appBarLayout;
private Toolbar toolbar;
+ private ActionBar actionBar;
private LinearLayout findOnPageLinearLayout;
private LinearLayout tabsLinearLayout;
private TabLayout tabLayout;
private SwipeRefreshLayout swipeRefreshLayout;
private ViewPager webViewPager;
+ private FrameLayout fullScreenVideoFrameLayout;
// Declare the class menus.
private Menu optionsMenu;
setContentView(R.layout.main_framelayout);
// Get handles for the views.
+ rootFrameLayout = findViewById(R.id.root_framelayout);
drawerLayout = findViewById(R.id.drawerlayout);
+ mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
appBarLayout = findViewById(R.id.appbar_layout);
toolbar = findViewById(R.id.toolbar);
findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
tabLayout = findViewById(R.id.tablayout);
swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
webViewPager = findViewById(R.id.webviewpager);
+ fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
// Get a handle for the navigation view.
NavigationView navigationView = findViewById(R.id.navigationview);
appCompatDelegate.setSupportActionBar(toolbar);
// Get a handle for the action bar.
- ActionBar actionBar = appCompatDelegate.getSupportActionBar();
+ actionBar = appCompatDelegate.getSupportActionBar();
- // This is needed to get rid of the Android Studio warning that the action bar might be null.
+ // Remove the incorrect lint warning below that the action bar might be null.
assert actionBar != null;
// Add the custom layout, which shows the URL text bar.
// Reapply any system UI flags and the ad in the free flavor.
if (displayingFullScreenVideo || inFullScreenBrowsingMode) { // The system is displaying a website or a video in full screen mode.
- // Get a handle for the root frame layouts.
- FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-
/* Hide the system bars.
* SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
* SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} else if (BuildConfig.FLAVOR.contentEquals("free")) { // The system in not in full screen mode.
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
// Resume the ad.
- AdHelper.resumeAd(findViewById(R.id.adview));
+ AdHelper.resumeAd(adView);
}
}
// Pause the ad or it will continue to consume resources in the background on the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
// Pause the ad.
- AdHelper.pauseAd(findViewById(R.id.adview));
+ AdHelper.pauseAd(adView);
}
}
// Store a handle for the options menu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons()`.
optionsMenu = menu;
- // Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step.
- updatePrivacyIcons(false);
-
// Get handles for the class menu items.
optionsPrivacyMenuItem = menu.findItem(R.id.javascript);
optionsRefreshMenuItem = menu.findItem(R.id.refresh);
MenuItem bookmarksMenuItem = menu.findItem(R.id.bookmarks);
MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
+ // Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(false);
+
// Only display third-party cookies if API >= 21
optionsThirdPartyCookiesMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
// Reload the ad for the free flavor if not in full screen mode.
if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
// Reload the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+ // `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+ AdHelper.loadAd(adView, getApplicationContext(), this, getString(R.string.ad_unit_id));
}
// `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug:
// close the bookmarks drawer.
drawerLayout.closeDrawer(GravityCompat.END);
} else if (displayingFullScreenVideo) { // A full screen video is shown.
- // Get a handle for the layouts.
- FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
- RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
- FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
// Re-enable the screen timeout.
fullScreenVideoFrameLayout.setKeepScreenOn(false);
if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { // Privacy Browser is currently in full screen browsing mode.
// Hide the banner ad in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
- AdHelper.hideAd(findViewById(R.id.adview));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Hide the banner ad.
+ AdHelper.hideAd(adView);
}
/* Hide the system bars.
// Reload the ad for the free flavor if not in full screen mode.
if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
- // Reload the ad.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Reload the ad. `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+ AdHelper.loadAd(adView, getApplicationContext(), this, getString(R.string.ad_unit_id));
}
} else if (currentWebView.canGoBack()) { // There is at least one item in the current WebView history.
// Get the current web back forward list.
searchURL = searchString;
}
- // Get a handle for the app compat delegate.
- AppCompatDelegate appCompatDelegate = getDelegate();
-
- // Get handles for the views that need to be modified.
- FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
- ActionBar actionBar = appCompatDelegate.getSupportActionBar();
-
- // Remove the incorrect lint warning below that the action bar might be null.
- assert actionBar != null;
-
// Apply the proxy.
applyProxy(false);
// Hide the banner ad in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
- AdHelper.hideAd(findViewById(R.id.adview));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Hide the banner ad.
+ AdHelper.hideAd(adView);
}
/* Hide the system bars.
// Show the banner ad in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
// Initialize the ads. If this isn't the first run, `loadAd()` will be automatically called instead.
- AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getSupportFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
+ // `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+ AdHelper.initializeAds(adView, getApplicationContext(), this, getSupportFragmentManager(), getString(R.string.ad_unit_id));
}
// Remove the `SYSTEM_UI` flags from the root frame layout.
}
}
- // Get a handle for the app compat delegate.
- AppCompatDelegate appCompatDelegate = getDelegate();
-
// Get handles for the activity views.
- FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
- RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
- ActionBar actionBar = appCompatDelegate.getSupportActionBar();
- LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout);
EditText urlEditText = findViewById(R.id.url_edittext);
- SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
- // Remove the incorrect lint warning below that the action bar might be null.
- assert actionBar != null;
// Get a handle for the activity
Activity activity = this;
// Hide the banner ad in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
- AdHelper.hideAd(findViewById(R.id.adview));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Hide the banner ad.
+ AdHelper.hideAd(adView);
}
/* Hide the system bars.
// Show the banner ad in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
- // Reload the ad.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Reload the ad. `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+ AdHelper.loadAd(adView, getApplicationContext(), activity, getString(R.string.ad_unit_id));
}
// Remove the `SYSTEM_UI` flags from the root frame layout.
// Enter full screen video.
@Override
public void onShowCustomView(View video, CustomViewCallback callback) {
- // Get a handle for the full screen video frame layout.
- FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
// Set the full screen video flag.
displayingFullScreenVideo = true;
// Pause the ad if this is the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
// The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.pauseAd(findViewById(R.id.adview));
+ AdHelper.pauseAd(adView);
}
// Hide the keyboard.
// Exit full screen video.
@Override
public void onHideCustomView() {
- // Get a handle for the full screen video frame layout.
- FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
// Re-enable the screen timeout.
fullScreenVideoFrameLayout.setKeepScreenOn(false);
// Hide the banner ad in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
- AdHelper.hideAd(findViewById(R.id.adview));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Hide the banner ad.
+ AdHelper.hideAd(adView);
}
/* Hide the system bars.
// Reload the ad for the free flavor if not in full screen mode.
if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
- // Reload the ad.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+ // Get a handle for the ad view. This cannot be a class variable because it changes with each ad load.
+ View adView = findViewById(R.id.adview);
+
+ // Reload the ad. `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+ AdHelper.loadAd(adView, getApplicationContext(), activity, getString(R.string.ad_unit_id));
}
}