Skip to content

Commit

Permalink
Added Jetpack Compose Sample LazyList Banner.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 654936228
  • Loading branch information
nventimigli authored and copybara-github committed Aug 2, 2024
1 parent 6c84c30 commit 859ba1e
Show file tree
Hide file tree
Showing 23 changed files with 964 additions and 143 deletions.
7 changes: 5 additions & 2 deletions kotlin/advanced/JetpackComposeDemo/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,18 @@ android {
dependencies {
implementation("androidx.activity:activity")
implementation("androidx.activity:activity-ktx")
implementation("androidx.activity:activity-compose:1.9.0")
implementation("androidx.activity:activity-compose:1.9.1")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.3")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4")
implementation(platform("androidx.compose:compose-bom:2024.06.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.navigation:navigation-compose:2.7.7")
implementation("com.google.android.gms:play-services-ads:23.2.0")
implementation("com.google.android.ump:user-messaging-platform:3.0.0")
implementation(project(":compose-util"))
implementation("androidx.navigation:navigation-runtime-ktx:2.7.7")
debugImplementation("androidx.compose.ui:ui-tooling")
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">

<application
android:name="com.google.android.gms.example.jetpackcomposedemo.MobileAdsApplication"
android:name="com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication"
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
@@ -0,0 +1,118 @@
/*
* 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.jetpackcomposedemo

import android.content.Context
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.tooling.preview.Preview
import com.example.jetpackcomposedemo.R
import com.google.android.gms.ads.AdListener
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.LoadAdError
import com.google.android.gms.compose_util.BannerAd
import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.BANNER_ADUNIT_ID
import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.TAG
import com.google.android.gms.example.jetpackcomposedemo.ui.theme.JetpackComposeDemoTheme

@Preview
@Composable
private fun BannerScreenPreview() {
JetpackComposeDemoTheme {
Surface(color = MaterialTheme.colorScheme.background) { BannerScreen() }
}
}

@Composable
fun BannerScreen(modifier: Modifier = Modifier) {
val context = LocalContext.current
val isPreviewMode = LocalInspectionMode.current
val deviceWidth = LocalConfiguration.current.screenWidthDp
var adView by remember { mutableStateOf(loadBannerAd(context, deviceWidth, isPreviewMode)) }
Column {
Button(
{
// Clean up the AdView after use.
adView.destroy()
adView = loadBannerAd(context, deviceWidth, isPreviewMode)
},
modifier = modifier.fillMaxWidth(),
) {
Text(text = context.getString(R.string.text_reload))
}
BannerAd(adView, modifier.fillMaxWidth())
}

// Clean up the AdView after use.
DisposableEffect(Unit) { onDispose { adView.destroy() } }
}

private fun loadBannerAd(context: Context, width: Int, isPreviewMode: Boolean): AdView {
val adView = AdView(context)

// Do not load the ad in preview mode.
if (isPreviewMode) {
return adView
}

adView.adUnitId = BANNER_ADUNIT_ID
val adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, width)
adView.setAdSize(adSize)

adView.adListener =
object : AdListener() {
override fun onAdLoaded() {
super.onAdLoaded()
Log.i(TAG, context.getString(R.string.banner_loaded))
}

override fun onAdFailedToLoad(error: LoadAdError) {
Log.e(TAG, context.getString(R.string.banner_failedToLoad))
}

override fun onAdImpression() {
super.onAdImpression()
Log.i(TAG, context.getString(R.string.banner_impression))
}

override fun onAdClicked() {
super.onAdClicked()
Log.i(TAG, context.getString(R.string.banner_clicked))
}
}

val adRequest = AdRequest.Builder().build()
adView.loadAd(adRequest)
return adView
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ package com.google.android.gms.example.jetpackcomposedemo

import android.app.Application

class MobileAdsApplication : Application() {
class GoogleMobileAdsApplication : Application() {
companion object {
const val TAG = "GoogleMobileAdsSample"

const val BANNER_ADUNIT_ID = "ca-app-pub-3940256099942544/6300978111"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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.jetpackcomposedemo

import android.app.Activity
import android.content.Context
import com.google.android.gms.example.jetpackcomposedemo.MainViewModel.Companion.TEST_DEVICE_HASHED_ID
import com.google.android.ump.ConsentDebugSettings
import com.google.android.ump.ConsentForm.OnConsentFormDismissedListener
import com.google.android.ump.ConsentInformation
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.FormError
import com.google.android.ump.UserMessagingPlatform

/**
* The Google Mobile Ads SDK provides the User Messaging Platform (Google's IAB Certified consent
* management platform) as one solution to capture consent for users in GDPR impacted countries.
* This is an example and you can choose another consent management platform to capture consent.
*/
class GoogleMobileAdsConsentManager private constructor(context: Context) {
private val consentInformation = UserMessagingPlatform.getConsentInformation(context)

/** Interface definition for a callback to be invoked when consent gathering is complete. */
fun interface OnConsentGatheringCompleteListener {
fun consentGatheringComplete(error: FormError?)
}

/** Determine if the app can request ads. */
val canRequestAds: Boolean
get() = consentInformation.canRequestAds()

/** Determine if the privacy options form is required. */
val isPrivacyOptionsRequired: Boolean
get() =
consentInformation.privacyOptionsRequirementStatus ==
ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED

/**
* Calls the UMP SDK methods to request consent information and load/show a consent form if
* necessary.
*/
fun gatherConsent(
activity: Activity,
onConsentGatheringCompleteListener: OnConsentGatheringCompleteListener,
) {
// For testing purposes, you can force a DebugGeography of EEA or NOT_EEA.
val debugSettings =
ConsentDebugSettings.Builder(activity)
// .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
.addTestDeviceHashedId(TEST_DEVICE_HASHED_ID)
.build()

val params = ConsentRequestParameters.Builder().setConsentDebugSettings(debugSettings).build()

// Requesting an update to consent information should be called on every app launch.
consentInformation.requestConsentInfoUpdate(
activity,
params,
{
UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity) { formError ->
// Consent has been gathered.
onConsentGatheringCompleteListener.consentGatheringComplete(formError)
}
},
{ requestConsentError ->
onConsentGatheringCompleteListener.consentGatheringComplete(requestConsentError)
},
)
}

/** Calls the UMP SDK method to show the privacy options form. */
fun showPrivacyOptionsForm(
activity: Activity,
onConsentFormDismissedListener: OnConsentFormDismissedListener,
) {
UserMessagingPlatform.showPrivacyOptionsForm(activity, onConsentFormDismissedListener)
}

companion object {
@Volatile private var instance: GoogleMobileAdsConsentManager? = null

fun getInstance(context: Context) =
instance
?: synchronized(this) {
instance ?: GoogleMobileAdsConsentManager(context).also { instance = it }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.google.android.gms.example.jetpackcomposedemo

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.jetpackcomposedemo.R
import com.google.android.gms.example.jetpackcomposedemo.ui.theme.JetpackComposeDemoTheme

@Composable
fun HomeScreen(
uiState: MainUiState,
navController: NavHostController,
modifier: Modifier = Modifier,
) {
Column {
Button(
onClick = { navController.navigate(NavDestinations.Banner.name) },
enabled = uiState.canRequestAds,
modifier = modifier.fillMaxWidth(),
) {
Text(LocalContext.current.getString(R.string.nav_banner))
}
Button(
onClick = { navController.navigate(NavDestinations.LazyBanner.name) },
enabled = uiState.canRequestAds,
modifier = modifier.fillMaxWidth(),
) {
Text(LocalContext.current.getString(R.string.nav_lazy_banner))
}
}
}

@Preview
@Composable
private fun HomeScreenPreview() {
JetpackComposeDemoTheme {
Surface(color = MaterialTheme.colorScheme.background) {
HomeScreen(MainUiState(), rememberNavController())
}
}
}
Loading

0 comments on commit 859ba1e

Please sign in to comment.