Skip to content

Commit

Permalink
Added kotlin preloading sample to APIDemo.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 693027376
  • Loading branch information
nventimigli authored and copybara-github committed Nov 4, 2024
1 parent 6b5af49 commit 696934f
Show file tree
Hide file tree
Showing 14 changed files with 442 additions and 3 deletions.
2 changes: 1 addition & 1 deletion kotlin/advanced/APIDemo/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ android {
compileSdk 34
defaultConfig {
applicationId "com.google.android.gms.example.apidemo"
minSdkVersion 21
minSdkVersion 24
targetSdkVersion 34
versionCode 1
versionName "1.0"
Expand Down
2 changes: 1 addition & 1 deletion kotlin/advanced/APIDemo/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:networkSecurityConfig="@xml/security"
android:networkSecurityConfig="@xml/network_security_config"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.core.view.GravityCompat
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.RequestConfiguration
import com.google.android.gms.example.apidemo.databinding.ActivityMainBinding
import com.google.android.gms.example.apidemo.preloading.AdMobPreloadingAdsFragment
import com.google.android.material.navigation.NavigationView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -71,6 +72,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
R.id.nav_admob_bannersizes -> AdMobBannerSizesFragment()
R.id.nav_collapsible_banner -> CollapsibleBannerFragment()
R.id.nav_admob_custommute -> AdMobCustomMuteThisAdFragment()
R.id.nav_admob_preload -> AdMobPreloadingAdsFragment()
R.id.nav_gam_adsizes -> AdManagerMultipleAdSizesFragment()
R.id.nav_gam_appevents -> AdManagerAppEventsFragment()
R.id.nav_gam_customtargeting -> AdManagerCustomTargetingFragment()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.gms.example.apidemo.preloading

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.gms.ads.AdFormat
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.preload.PreloadCallback
import com.google.android.gms.ads.preload.PreloadConfiguration
import com.google.android.gms.example.apidemo.MainActivity.Companion.LOG_TAG
import com.google.android.gms.example.apidemo.R
import com.google.android.gms.example.apidemo.databinding.FragmentPreloadMainBinding

/** Demonstrates how to preload ads. */
class AdMobPreloadingAdsFragment : Fragment() {
private lateinit var viewBinding: FragmentPreloadMainBinding
private val fragmentList = mutableListOf<PreloadItemFragment>()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
viewBinding = FragmentPreloadMainBinding.inflate(inflater, container, false)

// Initialize the fragment UI.
addFragments()

// Start preloading ads.
startPreload()

return viewBinding.root
}

// [START start_preload]
private fun startPreload() {
// Define the number of ads that can be preloaded for each ad unit.
val bufferSize = 2
// Define a list of PreloadConfiguration objects, specifying the ad unit ID and ad format for
// each ad unit to be preloaded.
val preloadConfigs =
listOf(
PreloadConfiguration.Builder(InterstitialFragment.AD_UNIT_ID, AdFormat.INTERSTITIAL)
.setBufferSize(bufferSize)
.build(),
PreloadConfiguration.Builder(RewardedFragment.AD_UNIT_ID, AdFormat.REWARDED)
.setBufferSize(bufferSize)
.build(),
PreloadConfiguration.Builder(AppOpenFragment.AD_UNIT_ID, AdFormat.APP_OPEN_AD)
.setBufferSize(bufferSize)
.build(),
)

// Define a callback to receive preload availability events.
val callback =
object : PreloadCallback {
override fun onAdsAvailable(preloadConfig: PreloadConfiguration) {
Log.i(LOG_TAG, "Preload ad for ${ preloadConfig.adFormat } is available.")
updateUI()
}

override fun onAdsExhausted(preloadConfig: PreloadConfiguration) {
Log.i(LOG_TAG, "Preload ad for configuration ${ preloadConfig.adFormat } is exhausted.")
updateUI()
}
}

// Start the preloading initialization process.
MobileAds.startPreload(this.requireContext(), preloadConfigs, callback)
}

// [END start_preload]

private fun addFragments() {
addFragment(AppOpenFragment())
addFragment(InterstitialFragment())
addFragment(RewardedFragment())
}

private fun <T : PreloadItemFragment> addFragment(fragment: T) {
val fragmentManager = getParentFragmentManager()
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.add(R.id.list_formats, fragment)
fragmentTransaction.commit()
fragmentList.add(fragment)
}

private fun updateUI() {
fragmentList.forEach { it.updateUI() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.gms.example.apidemo.preloading

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.gms.ads.appopen.AppOpenAd
import com.google.android.gms.example.apidemo.MainActivity.Companion.LOG_TAG
import com.google.android.gms.example.apidemo.R
import com.google.android.gms.example.apidemo.databinding.FragmentPreloadItemBinding

/** A [Fragment] subclass that preloads an app open ad. */
class AppOpenFragment : PreloadItemFragment() {

private lateinit var viewBinding: FragmentPreloadItemBinding

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
viewBinding = FragmentPreloadItemBinding.inflate(inflater, container, false)

// Initialize the UI.
initializeUI()

return viewBinding.root
}

private fun initializeUI() {
viewBinding.txtTitle.text = getText(R.string.preload_app_open)
viewBinding.btnShow.setOnClickListener {
pollAndShowAd()
updateUI()
}
updateUI()
}

private fun pollAndShowAd() {
// Verify that an ad is available before polling for an ad.
if (!AppOpenAd.isAdAvailable(requireContext(), AD_UNIT_ID)) {
Log.w(LOG_TAG, "Preloaded app open ad ${AD_UNIT_ID} is not available.")
return
}
// Polling returns the next available ad and load another ad in the background.
val ad = AppOpenAd.pollAd(requireContext(), AD_UNIT_ID)
activity?.let { activity -> ad?.show(activity) }
}

@Synchronized
override fun updateUI() {
if (AppOpenAd.isAdAvailable(requireContext(), AD_UNIT_ID)) {
viewBinding.txtStatus.text = getString(R.string.preload_available)
viewBinding.btnShow.isEnabled = true
} else {
viewBinding.txtStatus.text = getString(R.string.preload_exhausted)
viewBinding.btnShow.isEnabled = false
}
}

companion object {
const val AD_UNIT_ID = "ca-app-pub-3940256099942544/9257395921"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.gms.example.apidemo.preloading

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.example.apidemo.MainActivity.Companion.LOG_TAG
import com.google.android.gms.example.apidemo.R
import com.google.android.gms.example.apidemo.databinding.FragmentPreloadItemBinding

/** A [Fragment] subclass that preloads an interstitial ad. */
class InterstitialFragment : PreloadItemFragment() {

private lateinit var viewBinding: FragmentPreloadItemBinding

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
viewBinding = FragmentPreloadItemBinding.inflate(inflater, container, false)

initializeUI()

return viewBinding.root
}

private fun initializeUI() {
viewBinding.txtTitle.text = getText(R.string.preload_interstitial)
viewBinding.btnShow.setOnClickListener {
pollAndShowAd()
updateUI()
}
updateUI()
}

// [START pollAndShowAd]
private fun pollAndShowAd() {
// [START isAdAvailable]
// Verify that a preloaded ad is available before polling for an ad.
if (!InterstitialAd.isAdAvailable(requireContext(), AD_UNIT_ID)) {
Log.w(LOG_TAG, "Preloaded interstitial ad ${AD_UNIT_ID} is not available.")
return
}
// [END isAdAvailable]

// Polling returns the next available ad and load another ad in the background.
val ad = InterstitialAd.pollAd(requireContext(), AD_UNIT_ID)
activity?.let { activity -> ad?.show(activity) }
}

// [END pollAndShowAd]

@Synchronized
override fun updateUI() {
if (InterstitialAd.isAdAvailable(requireContext(), AD_UNIT_ID)) {
viewBinding.txtStatus.text = getString(R.string.preload_available)
viewBinding.btnShow.isEnabled = true
} else {
viewBinding.txtStatus.text = getString(R.string.preload_exhausted)
viewBinding.btnShow.isEnabled = false
}
}

companion object {
const val AD_UNIT_ID = "ca-app-pub-3940256099942544/1033173712"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.gms.example.apidemo.preloading

import androidx.fragment.app.Fragment

/** Abstract fragment for displaying the UI for a single ad preload format. */
abstract class PreloadItemFragment : Fragment() {
/** Updates the UI for the fragment. */
abstract fun updateUI()
}
Loading

0 comments on commit 696934f

Please sign in to comment.