2026/03/02

오늘의 이야기

https://andresand.medium.com/add-admob-ad-banner-using-android-compose-9ba78c8f1591



 


Add AdMob Ad banner using Android Compose


Tutorial shows how to display Google AdMob banner ads using Android Compose. Currently there is no official doc about AdMob and Android…


andresand.medium.com




 


jetpack compose 을 구현하면서 쉽게 광고판 달아보기 예제를 펌 했습니다.  읽어 보시면 도움이 될 것 같아요.


 


그래도 혹시나 해서 제가 만든 소스 의 일부를 공유해 봅니다. 


 


import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.KeyEvent.*
import android.view.View
import android.view.View.inflate
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Logout
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color.Companion.Red
import androidx.compose.ui.graphics.Color.Companion.White
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.viewinterop.AndroidViewBinding
import androidx.core.content.ContextCompat
import com.billcoreatech.multichat416.databean.*
import com.billcoreatech.multichat416.databinding.ActivityChatRoomBinding
import com.billcoreatech.multichat416.ui.theme.MultiChat416Theme
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.database.ChildEventListener
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.text.SimpleDateFormat
import java.util.*

class ChatRoomActivity : ComponentActivity() {

var TAG = "ChatRoomActivity"

lateinit var displayName:String
lateinit var auth: FirebaseAuth
lateinit var sp: SharedPreferences
lateinit var sdf:SimpleDateFormat
private val database = Firebase.database
private val chatroomViewModel by viewModels<ListViewModel>()
private val chatMessages = database.getReference("ChatMessage")
lateinit var df:SimpleDateFormat
lateinit var chatId:String
lateinit var startDt:String
lateinit var adapter:ChatAdapter
var chatMesgItems = ArrayList<ChatMessage>()
private set
lateinit var binding:ActivityChatRoomBinding
lateinit var retrofitApi:RetrofitApi

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

retrofitApi = RetrofitApi.create()
auth = Firebase.auth
sp = getSharedPreferences("MultiChat", MODE_PRIVATE)
sdf = SimpleDateFormat("yyyyMMddHHmmss")
df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
chatId = intent.getStringExtra("chatId") as String
startDt = intent.getSerializableExtra("startDt") as String
Log.e(TAG, "${startDt}")
displayName = auth.currentUser?.displayName.toString()

chatMesgItems.clear()
adapter = ChatAdapter(chatMesgItems, displayName)
binding = ActivityChatRoomBinding.inflate(layoutInflater)

setContent {
val isDarkTheme = remember { mutableStateOf(false) }
if(isDarkTheme.value){
this.window.statusBarColor = ContextCompat.getColor(this, R.color.softBlack)
}else{
this.window.statusBarColor = ContextCompat.getColor(this, R.color.softBlue)
}
MultiChat416Theme(darkTheme = isDarkTheme.value) {
Scaffold(topBar = {
ThemeAppBar(darkThemeState = isDarkTheme)
}, modifier = Modifier.fillMaxSize()
) { innerPadding ->
mainContent(Modifier.padding(innerPadding))
// 광고를 달아 봅니다.
AdvertView()
}
}
}
}

@Composable
fun ThemeAppBar(darkThemeState: MutableState<Boolean>) {

TopAppBar(title = {
Row {
Text(text = getString(R.string.app_name), modifier = Modifier.weight(8f))
Switch(checked = darkThemeState.value, onCheckedChange = {
darkThemeState.value = it
}, modifier = Modifier.weight(2f))
IconButton(onClick = { doLogOut() }) {
Icon(imageVector = Icons.Default.Logout, contentDescription = "LogOut")
}
}
})
}

@Composable
fun mainContent(padding: Modifier) {
Box(
Modifier
.fillMaxWidth()
.fillMaxHeight()
.scrollable(rememberScrollableState {
// view world deltas should be reflected in compose world
// components that participate in nested scrolling
it
}, Orientation.Vertical)
) {
AndroidViewBinding(ActivityChatRoomBinding::inflate) {
binding = this
chatMessages.child(chatId).orderByChild("crtDtim").startAfter(startDt.toString())
.addChildEventListener(object : ChildEventListener{
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
Log.e(TAG, "onChildAdded")
var chatMessageItem = snapshot.getValue(ChatMessage::class.java)
// 왜 2번씩 들어가는지 모르겠지만... 일단은 한번만 들어가게 하기 위해서
if (chatMessageItem != null && chatMesgItems.indexOf(chatMessageItem) < 0) {
if (sp.getBoolean("translateTy", false)
&& !sp.getString("languageCode", "kr").equals(chatMessageItem.locale)
) {
doGetTranslate(chatMessageItem)
}
chatMesgItems.add(chatMessageItem)
}
binding.rv.adapter = adapter
binding.rv.scrollToPosition(chatMesgItems.size - 1)
}

override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
Log.e(TAG, "onChildChanged")
}

override fun onChildRemoved(snapshot: DataSnapshot) {
Log.e(TAG, "onChildRemoved")
}

override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
Log.e(TAG, "onChildMoved")
}

override fun onCancelled(error: DatabaseError) {
Log.e(TAG, "onCancelled")
}

})
binding.sendIv.setOnClickListener {
doChatWrite()
}
binding.rv.setOnScrollChangeListener { view, i, i2, i3, i4 ->

}
binding.contentEt.setOnKeyListener(object : View.OnKeyListener{
override fun onKey(v: View?, keyCode: Int, event: KeyEvent?): Boolean {
if (event?.action == ACTION_DOWN && keyCode == KEYCODE_ENTER) {
doChatWrite()
}
return true
}
})
}
}
}

// 이 부분은 펌한 코드 입니다.
@Composable
fun AdvertView(modifier: Modifier = Modifier) {
val isInEditMode = LocalInspectionMode.current
if (isInEditMode) {
Text(
modifier = modifier
.fillMaxWidth()
.background(Red)
.padding(horizontal = 2.dp, vertical = 6.dp),
textAlign = TextAlign.Center,
color = White,
text = "Advert Here",
)
} else {
AndroidView(
modifier = modifier.fillMaxWidth(),
factory = { context ->
AdView(context).apply {
adSize = AdSize.BANNER
adUnitId = context.getString(R.string.admob_banner_test_id)
loadAd(AdRequest.Builder().build())
}
}
)
}
}

.....



private fun doLogOut() {
chatMessages.child(chatId).setValue(null)
var rIntent:Intent = intent
rIntent.putExtra("chatId", chatId)
setResult(RESULT_OK, rIntent)
finish()
}

}

 


이렇게 구현을 해 보면 다음과 같이 광고가 보입니다.


 


광고가 들어간 화면 예시



 





댓글 없음:

댓글 쓰기

오늘의 이야기

  계절의 여왕이라는 오월 길가에 장미가 싱그럽다. 아침 햇쌀을 맞는 장미를 보며, 나의 시간들도 싱그럽기를 기원한다.