From 4ce562261f47e06c454504262a24f61f46bb393d Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Mon, 21 Dec 2020 17:14:52 -0700 Subject: [PATCH] Fix a rare crash in `onBackPresses()`. https://redmine.stoutner.com/issues/651 --- app/build.gradle | 4 +- .../dialogs/AdConsentDialog.java | 4 +- .../privacybrowser/helpers/AdHelper.java | 64 +++++++-- app/src/free/res/layout/adview.xml | 3 +- .../activities/MainWebViewActivity.java | 124 ++++++++++-------- gradle.properties | 2 +- 6 files changed, 127 insertions(+), 74 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 30954025..be417985 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,6 +94,6 @@ dependencies { // Include the Google material library. implementation 'com.google.android.material:material:1.2.1' - // Only compile Firebase ads for the free flavor. - freeImplementation 'com.google.firebase:firebase-ads:19.6.0' + // Only compile AdMob ads for the free flavor. + freeImplementation 'com.google.android.gms:play-services-ads:19.6.0' } \ No newline at end of file diff --git a/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java b/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java index 60d507b0..d8d81e34 100644 --- a/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java +++ b/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java @@ -87,8 +87,8 @@ public class AdConsentDialog extends DialogFragment { // Update the ad consent database. adConsentDatabaseHelper.updateAdConsent(true); - // Load an ad. `getContext()` can be used instead of `getActivity.getApplicationContext()` on the minimum API >= 23. - AdHelper.loadAd(getActivity().findViewById(R.id.adview), getActivity().getApplicationContext(), getString(R.string.ad_unit_id)); + // Load an ad. `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23. + AdHelper.loadAd(getActivity().findViewById(R.id.adview), getActivity().getApplicationContext(), getActivity(), getString(R.string.ad_unit_id)); }); // Create an alert dialog from the alert dialog builder. diff --git a/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java b/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java index 60f22aac..4d4575d5 100644 --- a/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java +++ b/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2019 Soren Stoutner . + * Copyright © 2016-2020 Soren Stoutner . * * This file is part of Privacy Browser . * @@ -19,8 +19,11 @@ 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; @@ -32,16 +35,17 @@ import com.google.android.gms.ads.AdRequest; 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); @@ -51,45 +55,78 @@ public class AdHelper { // 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. @@ -99,6 +136,7 @@ public class AdHelper { 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; @@ -107,6 +145,7 @@ public class AdHelper { 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; @@ -115,6 +154,7 @@ public class AdHelper { 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; diff --git a/app/src/free/res/layout/adview.xml b/app/src/free/res/layout/adview.xml index 28d09acb..d573bda8 100644 --- a/app/src/free/res/layout/adview.xml +++ b/app/src/free/res/layout/adview.xml @@ -1,7 +1,7 @@