Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add InlineAdaptiveExample in Kotlin.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 581947574
JillSong authored and maddevrelgithubbot committed Nov 13, 2023
1 parent 5a002c9 commit 514c917
Showing 27 changed files with 1,033 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ jobs:
- "java/advanced/BannerRecyclerViewExample"
- "java/advanced/RewardedSSVExample"
- "kotlin/advanced/APIDemo"
- "kotlin/advanced/InlineAdaptiveBannerExample"
- "java/admob/AppOpenExample"
- "java/admob/BannerExample"
- "java/admob/FullScreenNativeExample"
2 changes: 1 addition & 1 deletion .github/workflows/build/folder-crawler.sh
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ set -eo pipefail
# If you are changing the expected_projects_count value, you likely want to be
# changing .github/workflows.build.yml to modify which samples are built
# through GitHub actions.
expected_projects_count=29
expected_projects_count=30
projects=()

# Reading all directories having a settings.gradle file into the projects
27 changes: 27 additions & 0 deletions kotlin/advanced/InlineAdaptiveBannerExample/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apply plugin: 'com.android.application'

android {
namespace 'com.google.android.gms.example.inlineadaptivebannerexample'
compileSdkVersion 33
defaultConfig {
applicationId "com.google.android.gms.example.inlineadaptivebannerexample"
minSdkVersion 19
multiDexEnabled true
targetSdkVersion 33
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.google.android.gms:play-services-ads:22.5.0'
}
30 changes: 30 additions & 0 deletions kotlin/advanced/InlineAdaptiveBannerExample/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# Copyright (C) 2016 Google, Inc.
#
# 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.

# Add project specific ProGuard rules here.
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# 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 *;
#}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.example.inlineadaptivebannerexample">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:taskAffinity=""
android:theme="@style/AppTheme">

<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/>

<activity
android:exported="true"
android:name="com.google.android.gms.example.inlineadaptivebannerexample.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package com.google.android.gms.example.inlineadaptivebannerexample

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
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 java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import org.json.JSONArray
import org.json.JSONException

/**
* A simple activity showing the use of [AdView] ads in a [RecyclerView] widget.
*
* The [RecyclerView] widget is a more advanced and flexible version of ListView. This widget helps
* simplify the display and handling of large data sets by allowing the layout manager to determine
* when to reuse (recycle) item views that are no longer visible to the user. Recycling views
* improves performance by avoiding the creation of unnecessary views or performing expensive
* findViewByID() lookups.
*/
class MainActivity : AppCompatActivity() {
// The RecyclerView that holds and displays banner ads and menu items.
private var recyclerView: RecyclerView? = null

// List of banner ads and MenuItems that populate the RecyclerView.
private val recyclerViewItems: MutableList<Any> = ArrayList()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recycler_view)

// Use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView.
recyclerView?.setHasFixedSize(true)

// Specify a linear layout manager.
val layoutManager: RecyclerView.LayoutManager = LinearLayoutManager(this)
recyclerView?.setLayoutManager(layoutManager)

// Update the RecyclerView item's list with menu items and banner ads.
addMenuItemsFromJson()
addBannerAds()
loadBannerAds()

// Specify an adapter.
val adapter: RecyclerView.Adapter<ViewHolder> = RecyclerViewAdapter(this, recyclerViewItems)
recyclerView?.setAdapter(adapter)
}

override fun onResume() {
for (item in recyclerViewItems) {
if (item is AdView) {
item.resume()
}
}
super.onResume()
}

override fun onPause() {
for (item in recyclerViewItems) {
if (item is AdView) {
item.pause()
}
}
super.onPause()
}

override fun onDestroy() {
for (item in recyclerViewItems) {
if (item is AdView) {
item.destroy()
}
}
super.onDestroy()
}

/** Adds banner ads to the items list. */
private fun addBannerAds() {
// Loop through the items array and place a new banner ad in every ith position in
// the items List.
var i = 0
while (i <= recyclerViewItems.size) {
val adView = AdView(this@MainActivity)
adView.setAdSize(AdSize.BANNER)
adView.adUnitId = AD_UNIT_ID
recyclerViewItems.add(i, adView)
i += ITEMS_PER_AD
}
}

/** Sets up and loads the banner ads. */
private fun loadBannerAds() {
// Load the first banner ad in the items list (subsequent ads will be loaded automatically
// in sequence).
loadBannerAd(0)
}

/** Loads the banner ads in the items list. */
private fun loadBannerAd(index: Int) {
if (index >= recyclerViewItems.size) {
return
}
val item =
recyclerViewItems[index] as? AdView
?: throw ClassCastException(
"Expected item at index " + index + " to be a banner ad" + " ad."
)

// Set an AdListener on the AdView to wait for the previous banner ad
// to finish loading before loading the next ad in the items list.
item.adListener =
object : AdListener() {
override fun onAdLoaded() {
super.onAdLoaded()
// The previous banner ad loaded successfully, call this method again to
// load the next ad in the items list.
loadBannerAd(index + ITEMS_PER_AD)
}

override fun onAdFailedToLoad(loadAdError: LoadAdError) {
// The previous banner ad failed to load. Call this method again to load
// the next ad in the items list.
val error =
String.format(
"domain: %s, code: %d, message: %s",
loadAdError.domain,
loadAdError.code,
loadAdError.message
)
Log.e(
"MainActivity",
"The previous banner ad failed to load with error: " +
error +
". Attempting to" +
" load the next banner ad in the items list."
)
loadBannerAd(index + ITEMS_PER_AD)
}
}

// Load the banner ad.
item.loadAd(AdRequest.Builder().build())
}

/** Adds [MenuItem]'s from a JSON file. */
private fun addMenuItemsFromJson() {
try {
val jsonDataString = readJsonDataFromFile()
val menuItemsJsonArray = JSONArray(jsonDataString)
for (i in 0 until menuItemsJsonArray.length()) {
val menuItemObject = menuItemsJsonArray.getJSONObject(i)
val menuItemName = menuItemObject.getString("name")
val menuItemDescription = menuItemObject.getString("description")
val menuItemPrice = menuItemObject.getString("price")
val menuItemCategory = menuItemObject.getString("category")
val menuItemImageName = menuItemObject.getString("photo")
val menuItem =
MenuItem(
menuItemName,
menuItemDescription,
menuItemPrice,
menuItemCategory,
menuItemImageName
)
recyclerViewItems.add(menuItem)
}
} catch (exception: IOException) {
Log.e(MainActivity::class.java.name, "Unable to parse JSON file.", exception)
} catch (exception: JSONException) {
Log.e(MainActivity::class.java.name, "Unable to parse JSON file.", exception)
}
}

/**
* Reads the JSON file and converts the JSON data to a [String].
*
* @return A [String] representation of the JSON data.
* @throws IOException if unable to read the JSON file.
*/
@Throws(IOException::class)
private fun readJsonDataFromFile(): String {
var inputStream: InputStream? = null
val builder = StringBuilder()
try {
var jsonDataString: String? = null
inputStream = resources.openRawResource(R.raw.menu_items_json)
val bufferedReader = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
while (bufferedReader.readLine().also { jsonDataString = it } != null) {
builder.append(jsonDataString)
}
} finally {
inputStream?.close()
}
return builder.toString()
}

companion object {
// A banner ad is placed in every 8th position in the RecyclerView.
const val ITEMS_PER_AD = 8
private const val AD_UNIT_ID = "ca-app-pub-3940256099942544/4177191030"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.google.android.gms.example.inlineadaptivebannerexample

/**
* The [MenuItem] class.
*
* Defines the attributes for a restaurant menu item.
*/
internal class MenuItem(
val name: String,
val description: String,
val price: String,
val category: String,
val imageName: String
)
Loading

0 comments on commit 514c917

Please sign in to comment.