Skip to content

Commit

Permalink
Implement ironsource ad network (#64)
Browse files Browse the repository at this point in the history
* Add ironsource packages

* Modify chat view control

* Implement ad network config

* Implement ironsource ad display
  • Loading branch information
aqua-ix authored Mar 13, 2024
1 parent d58c449 commit 245cc00
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 20 deletions.
5 changes: 4 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,12 @@ dependencies {
implementation(platform("com.google.firebase:firebase-bom:32.7.4"))
implementation("com.google.firebase:firebase-config-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")

implementation("com.google.android.gms:play-services-appset:16.0.2")
implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
implementation("com.google.android.gms:play-services-basement:18.3.0")
implementation(files("libs/imobileSdkAds.jar"))
implementation("com.ironsource.sdk:mediationsdk:7.9.0")
implementation("com.ironsource:adqualitysdk:7.17.0")
}

secrets {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID "/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID "/>

<application
android:name=".Application"
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/java/com/aqua_ix/youbimiku/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.aqua_ix.youbimiku

class Constants {
companion object {
const val ARGUMENT_CANCELABLE="cancelable"
const val ARGUMENT_CANCELABLE = "cancelable"
const val OPENAI_MODEL = "gpt-3.5-turbo"
}
}
Expand All @@ -11,7 +11,15 @@ class RemoteConfigKey {
companion object {
const val MAX_USER_TEXT_LENGTH = "max_user_text_length"
const val MAX_TOKENS = "max_tokens"
const val AD_NETWORK = "ad_network"
const val AD_DISPLAY_REQUEST_TIMES = "ad_display_request_times"
const val OPENAI_ENABLED = "openai_enabled"
}

class AdNetwork {
companion object {
const val IMOBILE = "imobile"
const val IRONSOURCE = "ironsource"
}
}
}
179 changes: 163 additions & 16 deletions app/src/main/java/com/aqua_ix/youbimiku/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.*
import android.view.ViewGroup.LayoutParams.*
import android.widget.FrameLayout
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
Expand All @@ -32,6 +33,12 @@ import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfigSettings
import com.ironsource.mediationsdk.*
import com.ironsource.mediationsdk.adunit.adapter.utility.AdInfo
import com.ironsource.mediationsdk.integration.IntegrationHelper
import com.ironsource.mediationsdk.logger.IronSourceError
import com.ironsource.mediationsdk.sdk.LevelPlayBannerListener
import com.ironsource.mediationsdk.sdk.LevelPlayInterstitialListener
import jp.co.imobile.sdkads.android.FailNotificationReason
import jp.co.imobile.sdkads.android.ImobileSdkAd
import jp.co.imobile.sdkads.android.ImobileSdkAdListener
Expand All @@ -49,6 +56,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
private lateinit var firebaseDatabase: FirebaseDatabase
private lateinit var appDatabase: AppDatabase
private lateinit var navMenu: Menu
private lateinit var ironSourceBannerLayout: IronSourceBannerLayout

private var openAIPreviousResponse = ""

Expand All @@ -69,14 +77,13 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
detectIntent = DetectIntent(this, getDialogFlowSession())

initChatView()
initBanner()
initInterstitial()
initRemoteConfig()
initDatabase()
showInAppReviewIfNeeded()

setupOpenAI()
setupChat()
setupAdNetwork()
}

private fun initRemoteConfig() {
Expand Down Expand Up @@ -135,7 +142,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
}

withContext(Dispatchers.Main) {
messages.forEach(binding.chatView::receive)
binding.chatView.getMessageView().init(messages)
}

if (messages.isEmpty()) {
Expand All @@ -144,10 +151,24 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
}
}

private fun initBanner() {
private fun setupAdNetwork() {
if (FLAVOR == "noAds") {
Log.d(TAG, "Ad network is disabled by flavor.")
return
}
when (remoteConfig.getString(RemoteConfigKey.AD_NETWORK)) {
RemoteConfigKey.AdNetwork.IMOBILE -> {
initImobileBanner()
initImobileInterstitial()
}

RemoteConfigKey.AdNetwork.IRONSOURCE -> {
initIronSource()
}
}
}

private fun initImobileBanner() {
ImobileSdkAd.registerSpotInline(
this,
IMOBILE_PID,
Expand Down Expand Up @@ -184,10 +205,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
})
}

private fun initInterstitial() {
if (FLAVOR == "noAds") {
return
}
private fun initImobileInterstitial() {
ImobileSdkAd.registerSpotFullScreen(
this,
IMOBILE_PID,
Expand All @@ -197,6 +215,95 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
ImobileSdkAd.start(IMOBILE_INTERSTITIAL_SID)
}

private fun initIronSource() {
initIronSourceBanner()
initIronSourceInterstitial()
IronSource.init(
this,
IRONSOURCE_APP_KEY,
IronSource.AD_UNIT.BANNER,
IronSource.AD_UNIT.INTERSTITIAL
)
IronSource.loadBanner(ironSourceBannerLayout)
IronSource.loadInterstitial()
}

private fun initIronSourceBanner() {
val size = ISBannerSize.BANNER
ironSourceBannerLayout = IronSource.createBanner(this, size)
ironSourceBannerLayout.apply {
ironSourceBannerLayout.levelPlayBannerListener = object : LevelPlayBannerListener {
override fun onAdLoaded(adInfo: AdInfo) {
Log.d(TAG, "IronSource banner loaded: $adInfo")
val mlp = binding.chatView.layoutParams as ViewGroup.MarginLayoutParams
mlp.topMargin = ironSourceBannerLayout.height
}

override fun onAdLoadFailed(error: IronSourceError) {
Log.e(TAG, "IronSource banner load failed: $error")
}

override fun onAdClicked(adInfo: AdInfo) {
Log.d(TAG, "IronSource banner clicked: $adInfo")
}

override fun onAdScreenPresented(adInfo: AdInfo) {
Log.d(TAG, "IronSource banner screen presented: $adInfo")
}

override fun onAdScreenDismissed(adInfo: AdInfo) {
Log.d(TAG, "IronSource banner screen dismissed: $adInfo")
}

override fun onAdLeftApplication(adInfo: AdInfo) {
Log.d(TAG, "IronSource banner left application: $adInfo")
}
}

val layoutParams = FrameLayout.LayoutParams(
WRAP_CONTENT, WRAP_CONTENT
).apply {
gravity = Gravity.TOP or Gravity.CENTER
}
addContentView(ironSourceBannerLayout, layoutParams)
if (BUILD_TYPE == "debug") {
IntegrationHelper.validateIntegration(context);
}
}
}

private fun initIronSourceInterstitial() {
IronSource.setLevelPlayInterstitialListener(object : LevelPlayInterstitialListener {
override fun onAdReady(adInfo: AdInfo) {
Log.d(TAG, "IronSource interstitial ready: $adInfo")
}

override fun onAdLoadFailed(error: IronSourceError?) {
Log.e(TAG, "IronSource interstitial load failed: $error")
}

override fun onAdOpened(adInfo: AdInfo) {
Log.d(TAG, "IronSource interstitial opened: $adInfo")
}

override fun onAdShowSucceeded(adInfo: AdInfo) {
Log.d(TAG, "IronSource interstitial show succeeded: $adInfo")
}

override fun onAdShowFailed(error: IronSourceError?, adInfo: AdInfo) {
Log.e(TAG, "IronSource interstitial show failed: $error, $adInfo")
}

override fun onAdClicked(adInfo: AdInfo) {
Log.d(TAG, "IronSource interstitial clicked: $adInfo")
}

override fun onAdClosed(adInfo: AdInfo) {
Log.d(TAG, "IronSource interstitial closed: $adInfo")
}
})
}

private fun getMikuAccountFromAIModel(): User {
return if (getAIModel(this) == (AIModelConfig.OPEN_AI.name)) {
val face = BitmapFactory.decodeResource(resources, R.drawable.normal)
Expand Down Expand Up @@ -259,8 +366,13 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
}

private fun setupOpenAI() {
val reference = firebaseDatabase.getReference("secrets/openai")
if (!remoteConfig.getBoolean(RemoteConfigKey.OPENAI_ENABLED)) {
Log.e(TAG, "OpenAI is disabled by remote config.")
onOpenAIError()
return
}

val reference = firebaseDatabase.getReference("secrets/openai")
reference.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val apiKey = dataSnapshot.child("apiKey").getValue(String::class.java)
Expand Down Expand Up @@ -367,9 +479,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
appDatabase.messageDao().deleteAll()
}

// Activityを再起動する
finish()
startActivity(intent)
binding.chatView.getMessageView().removeAll()
}

private fun openInAppReview() {
Expand Down Expand Up @@ -493,8 +603,20 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
}

if (count >= remoteConfig.getDouble(RemoteConfigKey.AD_DISPLAY_REQUEST_TIMES)) {
ImobileSdkAd.showAd(this, IMOBILE_INTERSTITIAL_SID)
Log.d(TAG, "Ad display request count: $count")
setOpenAIRequestCount(applicationContext, 0)
when (remoteConfig.getString(RemoteConfigKey.AD_NETWORK)) {
RemoteConfigKey.AdNetwork.IMOBILE -> {
Log.d(TAG, "ImobileSdkAd.showAd")
ImobileSdkAd.showAd(this, IMOBILE_INTERSTITIAL_SID)
}

RemoteConfigKey.AdNetwork.IRONSOURCE -> {
Log.d(TAG, "IronSource.showInterstitial")
IronSource.showInterstitial()
setOpenAIRequestCount(applicationContext, 0)
}
}
}
}

Expand Down Expand Up @@ -574,19 +696,44 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, DialogListener {
}

public override fun onPause() {
ImobileSdkAd.stop(IMOBILE_BANNER_SID)
when (remoteConfig.getString(RemoteConfigKey.AD_NETWORK)) {
RemoteConfigKey.AdNetwork.IMOBILE -> {
ImobileSdkAd.stop(IMOBILE_BANNER_SID)
}

RemoteConfigKey.AdNetwork.IRONSOURCE -> {
IronSource.onPause(this)
}
}
super.onPause()
}

public override fun onResume() {
ImobileSdkAd.start(IMOBILE_BANNER_SID)
when (remoteConfig.getString(RemoteConfigKey.AD_NETWORK)) {
RemoteConfigKey.AdNetwork.IMOBILE -> {
ImobileSdkAd.start(IMOBILE_BANNER_SID)
}

RemoteConfigKey.AdNetwork.IRONSOURCE -> {
IronSource.onResume(this)
}
}
super.onResume()
}

public override fun onDestroy() {
detectIntent.resetContexts()
scope.coroutineContext.cancel()
ImobileSdkAd.activityDestroy()
when (remoteConfig.getString(RemoteConfigKey.AD_NETWORK)) {
RemoteConfigKey.AdNetwork.IMOBILE -> {
ImobileSdkAd.stop(IMOBILE_BANNER_SID)
ImobileSdkAd.stop(IMOBILE_INTERSTITIAL_SID)
}

RemoteConfigKey.AdNetwork.IRONSOURCE -> {
IronSource.destroyBanner(ironSourceBannerLayout)
}
}
super.onDestroy()
}

Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/xml/remote_config_defaults.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<key>max_tokens</key>
<value>0</value>
</entry>
<entry>
<key>ad_network</key>
<value>imobile</value>
</entry>
<entry>
<key>ad_display_request_times</key>
<value>30</value>
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ allprojects {
google()
mavenCentral()
maven(url = "https://jitpack.io")
maven(url = "https://android-sdk.is.com/")
}
}

Expand Down
3 changes: 2 additions & 1 deletion secrets.defaults.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ TRANSLATE_END_POINT=TRANSLATE_END_POINT
IMOBILE_PID=IMOBILE_PID
IMOBILE_MID=IMOBILE_MID
IMOBILE_BANNER_SID=IMOBILE_BANNER_SID
IMOBILE_INTERSTITIAL_SID=IMOBILE_INTERSTITIAL_SID
IMOBILE_INTERSTITIAL_SID=IMOBILE_INTERSTITIAL_SID
IRONSOURCE_APP_KEY=IRONSOURCE_APP_KEY

0 comments on commit 245cc00

Please sign in to comment.