Я загрузил межстраничное объявление в начале действия, но когда я его показываю, оно возвращает нулевое значение. Журнал.
2022-11-18 09:53:45.102 18604-18604/com.blogspot.bunnylists.maate D/ADAD: Ad was loaded.
2022-11-18 09:54:17.358 18604-18604/com.blogspot.bunnylists.maate D/ADAD: The interstitial wasn't loaded yet.
Приложение представляет собой приложение с одним действием. Я следовал официальной документации по внедрению межстраничной рекламы. Весь код, связанный с рекламой, находится в MainActivity. После нажатия кнопки я показываю полноэкранный фрагмент в MainActivityLayout. Я реализовал ReyclerView в этом фрагменте. Когда recyclerView загрузил некоторое количество просмотров на экране, я хочу показать объявление. Я вызываю метод showAd() класса MainActivity внутри метода onBindViewHolder.
class MainActivity : AppCompatActivity() {
private lateinit var bind : ActivityMainBinding
private lateinit var viewModel: MainActivityViewModel
private var mInterstitialAd: InterstitialAd? = null
val TAG = "ADAD"
val adRequest = AdRequest.Builder().build()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bind = DataBindingUtil.setContentView(this, com.blogspot.bunnylists.maate.R.layout.activity_main)
val repository = (application as MyApplication).repository
viewModel = ViewModelProvider(this, MyViewModelFactory(repository, "MainActivity"))[MainActivity2ViewModel::class.java]
//Here I am loading the Ad at the creation of the MainActivity
loadAd()
mInterstitialAd?.fullScreenContentCallback = object: FullScreenContentCallback() {
override fun onAdClicked() {
// Called when a click is recorded for an ad.
Log.d(TAG, "Ad was clicked.")
}
override fun onAdDismissedFullScreenContent() {
// Called when ad is dismissed.
Log.d(TAG, "Ad dismissed fullscreen content.")
mInterstitialAd = null
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
// Called when ad fails to show.
Log.e(TAG, "Ad failed to show fullscreen content.")
mInterstitialAd = null
}
override fun onAdImpression() {
// Called when an impression is recorded for an ad.
Log.d(TAG, "Ad recorded an impression.")
}
override fun onAdShowedFullScreenContent() {
// Called when ad is shown.
Log.d(TAG, "Ad showed fullscreen content.")
}
}
}
// The method which is called from the onBindViewHolder
fun showAd() {
if (mInterstitialAd != null) {
Log.d(TAG, "showing Ad")
mInterstitialAd?.show(this)
loadAd()
} else {
Log.d(TAG, "The interstitial wasn't loaded yet.")
}
}
private fun loadAd(){
InterstitialAd.load(this,
"ca-app-pub-3940256099942544/1033173712",
adRequest,
object : InterstitialAdLoadCallback() {
override fun onAdFailedToLoad(adError: LoadAdError) {
Log.d(TAG, adError.toString())
mInterstitialAd = null
}
override fun onAdLoaded(interstitialAd: InterstitialAd) {
Log.d(TAG, "Ad was loaded.")
mInterstitialAd = interstitialAd
}
})
}
}
onBindViewHolder:
override fun onBindViewHolder(holder: MyViewHolder, position: Int){
if (position%20==0){
MainActivity().showAd()
}
}
Также вам нужно добавить свой полноэкранный обратный вызов внутри вашего AdLoadedCallback. В настоящее время вы вообще не добавляете его, потому что вы добавляете его с нулевым безопасным вызовом в то время, когда объявление является нулевым.
Не могли бы вы поделиться некоторыми ресурсами, я не понял, что вы пытаетесь сказать.
Никогда не делайте этого:
MainActivity()
Вышеупомянутое создает экземпляр Activity, вызывая его конструктор. Это имеет две проблемы:
Вам нужно открыть обратный вызов, показывающий рекламу, от вашего адаптера и вызвать его вместо этого:
class MyAdapter: RecyclerView.Adapter<SomeType, SomeViewHolder>() {
var onRequestAd: (()->Unit)? = null
override fun onBindViewHolder(holder: MyViewHolder, position: Int){
if (position%20==0){
onRequestAd?.invoke()
}
//...
}
}
Затем в своей деятельности, сразу после создания экземпляра адаптера, вы должны настроить прослушиватель на вызов showAd()
:
val adapter = MyAdapter()
adapter.onRequestAd = ::showAd // or { showAd() }
bind.adapter = adapter
Отдельную проблему я упомянул в ваших комментариях. В этой строке:
mInterstitialAd?.fullScreenContentCallback = object: FullScreenContentCallback() {
вы звоните в тот момент, когда mInterstitialAd
все еще имеет значение null, поэтому он ничего не делает, и ваш обратный вызов никогда не используется. Вам нужно переместить этот код внутрь функции обратного вызова onAdLoaded
, чтобы он добавлялся к объявлению после его создания и добавлялся каждый раз, когда вы загружаете новое объявление.
Кстати, вам может понадобиться более сложный способ определения времени показа рекламы. Как бы то ни было, я думаю, что если 20-й элемент находится за пределами экрана, а пользователь покачивает его вверх и вниз, он будет запрашивать рекламу снова и снова. Вы можете добавить таймер, например:
private var lastAdTime = 0L
override fun onBindViewHolder(holder: MyViewHolder, position: Int){
if (position%20==0 && lastAdTime + 3000 < System.currentTimeMillis()){
onRequestAd()
lastAdTime = System.currentTimeMillis()
}
}
Большое спасибо за то, что уделили свое драгоценное время.
Не могли бы вы также взглянуть и дать несколько советов по этому вопросу: stackoverflow.com/q/74485942/16350333
Вы создаете новую активность, вызывая ее конструктор, что вы никогда не должны делать и не будет работать (и может вызвать сбои). Вместо этого вам нужно открыть свойство слушателя из вашего адаптера. Activity может передать ему прослушиватель, который вызывает
showAd()
. Вы можете найти примеры шаблона прослушивателя кликов с помощью адаптеров, но просто измените его на прослушиватель, когда показывать рекламу.