-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Jetpack Compose Native Compose Sample.
PiperOrigin-RevId: 634082840
- Loading branch information
1 parent
fff53bc
commit 28a986e
Showing
40 changed files
with
2,320 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
plugins { | ||
id("com.android.application") | ||
id("org.jetbrains.kotlin.android") | ||
} | ||
|
||
android { | ||
namespace = "com.example.jetpackcomposedemo" | ||
compileSdk = 34 | ||
|
||
defaultConfig { | ||
applicationId = "com.google.android.gms.example.jetpackcomposedemo" | ||
minSdk = 24 | ||
targetSdk = 34 | ||
versionCode = 1 | ||
versionName = "1.0" | ||
|
||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" | ||
vectorDrawables { useSupportLibrary = true } | ||
} | ||
|
||
buildTypes { | ||
release { | ||
isMinifyEnabled = false | ||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
} | ||
kotlinOptions { jvmTarget = "1.8" } | ||
buildFeatures { | ||
compose = true | ||
viewBinding = true | ||
} | ||
composeOptions { kotlinCompilerExtensionVersion = "1.5.1" } | ||
packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } | ||
} | ||
|
||
dependencies { | ||
implementation("androidx.core:core-ktx:1.13.1") | ||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.0") | ||
implementation("androidx.activity:activity-compose:1.9.0") | ||
implementation(platform("androidx.compose:compose-bom:2024.05.00")) | ||
implementation("androidx.compose.ui:ui:1.7.0-beta03") | ||
implementation("androidx.compose.ui:ui-graphics") | ||
implementation("androidx.compose.ui:ui-tooling-preview") | ||
implementation("androidx.compose.material3:material3") | ||
implementation("com.google.android.gms:play-services-ads:23.1.0") | ||
implementation("com.google.android.ump:user-messaging-platform:2.2.0") | ||
implementation("com.google.android.gms:play-services-ads-lite:23.1.0") | ||
testImplementation("junit:junit:4.13.2") | ||
androidTestImplementation("androidx.test.ext:junit:1.1.5") | ||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") | ||
androidTestImplementation(platform("androidx.compose:compose-bom:2024.05.00")) | ||
androidTestImplementation("androidx.compose.ui:ui-test-junit4") | ||
debugImplementation("androidx.compose.ui:ui-tooling") | ||
debugImplementation("androidx.compose.ui:ui-test-manifest") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
41 changes: 41 additions & 0 deletions
41
kotlin/advanced/JetpackComposeDemo/app/src/main/AndroidManifest.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools"> | ||
|
||
<application | ||
android:taskAffinity="" | ||
android:name="com.google.android.gms.example.jetpackcomposedemo.MobileAdsApplication" | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/Theme.JetpackComposeDemo" | ||
tools:targetApi="31"> | ||
<meta-data | ||
android:name="com.google.android.gms.ads.APPLICATION_ID" | ||
android:value="ca-app-pub-3940256099942544~3347511713" /> | ||
<meta-data android:name="com.google.android.gms.ads.flag.NATIVE_AD_DEBUGGER_ENABLED" | ||
android:value="true" /> | ||
<activity | ||
android:name="com.google.android.gms.example.jetpackcomposedemo.MainActivity" | ||
android:exported="true" | ||
android:theme="@style/Theme.JetpackComposeDemo"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
<activity | ||
android:name="com.google.android.gms.example.jetpackcomposedemo.NativeActivity" | ||
android:exported="true" | ||
android:theme="@style/Theme.JetpackComposeDemo"> | ||
</activity> | ||
<activity | ||
android:name="com.google.android.gms.example.jetpackcomposedemo.NativeComposeActivity" | ||
android:exported="true" | ||
android:theme="@style/Theme.JetpackComposeDemo"> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
153 changes: 153 additions & 0 deletions
153
...src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package com.google.android.gms.example.jetpackcomposedemo | ||
|
||
import android.app.Activity | ||
import android.content.Context | ||
import android.util.Log | ||
import androidx.annotation.IntDef | ||
import androidx.compose.runtime.mutableIntStateOf | ||
import androidx.compose.runtime.mutableStateOf | ||
import com.google.android.gms.ads.AdError | ||
import com.google.android.gms.ads.MobileAds | ||
import com.google.android.ump.* | ||
import java.util.concurrent.atomic.AtomicBoolean | ||
|
||
/** This class manages the process of obtaining consent for and initializing Google Mobile Ads. */ | ||
class GoogleMobileAdsManager { | ||
|
||
/** Represents initialization states for the Google Mobile Ads SDK. */ | ||
object MobileAdsState { | ||
/** Initial start state. */ | ||
const val UNINITIALIZED = 0 | ||
|
||
/** User consent required but not yet obtained. */ | ||
const val CONSENT_REQUIRED = 2 | ||
|
||
/** User consent obtained. Personalized vs non-personalized undefined. */ | ||
const val CONSENT_OBTAINED = 3 | ||
|
||
/** Google Mobile Ads SDK initialized successfully. */ | ||
const val INITIALIZED = 100 | ||
|
||
/** An error occurred when requesting consent. */ | ||
const val CONSENT_REQUEST_ERROR = -1 | ||
|
||
/** An error occurred when showing the privacy options form. */ | ||
const val CONSENT_FORM_ERROR = -2 | ||
|
||
@Target(AnnotationTarget.TYPE) | ||
@IntDef( | ||
UNINITIALIZED, | ||
INITIALIZED, | ||
CONSENT_REQUIRED, | ||
CONSENT_OBTAINED, | ||
CONSENT_REQUEST_ERROR, | ||
CONSENT_FORM_ERROR, | ||
) | ||
@Retention(AnnotationRetention.SOURCE) | ||
annotation class State | ||
} | ||
|
||
/** Represents current initialization states for the Google Mobile Ads SDK. */ | ||
var mobileAdsState = mutableIntStateOf(MobileAdsState.UNINITIALIZED) | ||
|
||
/** Indicates whether the app has completed the steps for gathering updated user consent. */ | ||
var canRequestAds = mutableStateOf(false) | ||
|
||
/** Helper variable to determine if the privacy options form is required. */ | ||
var isPrivacyOptionsRequired = mutableStateOf(false) | ||
|
||
private var isMobileAdsInitializeCalled = AtomicBoolean(false) | ||
|
||
private lateinit var consentInformation: ConsentInformation | ||
|
||
/** | ||
* Initiates the consent process and initializes the Google Mobile Ads SDK if the SDK is | ||
* UNINITIALIZED. | ||
* | ||
* @param activity Activity responsible for initializing the Google Mobile Ads SDK. | ||
* @param consentRequestParameters Parameters for the consent request form. | ||
*/ | ||
fun initializeWithConsent( | ||
activity: Activity, | ||
consentRequestParameters: ConsentRequestParameters, | ||
) { | ||
|
||
if (isMobileAdsInitializeCalled.getAndSet(true)) { | ||
return | ||
} | ||
|
||
consentInformation = UserMessagingPlatform.getConsentInformation(activity) | ||
|
||
consentInformation.requestConsentInfoUpdate( | ||
activity, | ||
consentRequestParameters, | ||
{ | ||
// Success callback. | ||
showConsentFormIfRequired(activity) { error -> | ||
if (error != null) { | ||
Log.w(TAG, "Consent form error: ${error.errorCode} - ${error.message}") | ||
mobileAdsState.intValue = MobileAdsState.CONSENT_FORM_ERROR | ||
} else { | ||
mobileAdsState.intValue = MobileAdsState.CONSENT_OBTAINED | ||
} | ||
canRequestAds.value = consentInformation.canRequestAds() | ||
isPrivacyOptionsRequired.value = | ||
consentInformation.privacyOptionsRequirementStatus == | ||
ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED | ||
if (consentInformation.canRequestAds()) { | ||
initializeMobileAdsSdk(activity) | ||
} | ||
} | ||
}, | ||
{ formError -> | ||
// Failure callback. | ||
Log.w(TAG, "Consent info update error: ${formError.errorCode} - ${formError.message}") | ||
mobileAdsState.intValue = MobileAdsState.CONSENT_REQUEST_ERROR | ||
}, | ||
) | ||
|
||
// This sample attempts to load ads using consent obtained from the previous session. | ||
if (consentInformation.canRequestAds()) { | ||
initializeMobileAdsSdk(activity) | ||
} | ||
} | ||
|
||
/** Shows the update consent form. */ | ||
fun showPrivacyOptionsForm(activity: Activity) { | ||
UserMessagingPlatform.showPrivacyOptionsForm(activity) { error -> | ||
if (error != null) { | ||
mobileAdsState.intValue = MobileAdsState.CONSENT_FORM_ERROR | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Initializes Mobile Ads SDK. | ||
* | ||
* @param activity Activity responsible for initializing the Google Mobile Ads SDK. | ||
*/ | ||
fun initializeMobileAdsSdk(activity: Activity) { | ||
MobileAds.initialize(activity) { | ||
Log.d(TAG, "Mobile Ads SDK initialized") | ||
mobileAdsState.intValue = MobileAdsState.INITIALIZED | ||
} | ||
} | ||
|
||
/** | ||
* Opens the Ad Inspector UI. | ||
* | ||
* @param context The application or activity context required for launching the inspector. | ||
* @param onAdInspectorResult A callback to handle the result of opening the Ad Inspector. | ||
*/ | ||
fun openAdInspector(context: Context, onAdInspectorResult: (AdError?) -> Unit) { | ||
MobileAds.openAdInspector(context) { error -> onAdInspectorResult(error) } | ||
} | ||
|
||
private fun showConsentFormIfRequired(activity: Activity, onFormResult: (FormError?) -> Unit) { | ||
UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity, onFormResult) | ||
} | ||
|
||
companion object { | ||
const val TAG = "GoogleMobileAdsSample" | ||
} | ||
} |
Oops, something went wrong.