I faced a strange bug with admob native ads. Everything works fine except that I cannot find url value for an ads on callback and that UnifiedNativeAdView is not clickable, even button inside don't go anywhere as I use admob templates.
Here is the XML view code:
<com.google.android.gms.ads.formats.UnifiedNativeAdView
android:paddingTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/native_ad_view"
android:background="#000000"
android:elevation="20dp">
<LinearLayout
android:id="@+id/native_ad_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
style="@style/AdAttribution"
android:id="@+id/native_ad_attribution"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/native_ad_inside_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="1"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:maxWidth="85dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/ad_headline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:maxLines="3"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:textSize="16sp"
android:textStyle="bold" />
<Button
android:id="@+id/ad_call_to_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:maxWidth="50dp"
android:maxLines="3"
android:textSize="12sp"
/>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.formats.UnifiedNativeAdView>
Code of Viewholder:
inner class TripViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val adView: UnifiedNativeAdView = view.native_ad_view as UnifiedNativeAdView
var layoutView: LinearLayout = view.native_ad_layout
var insideLayoutView: LinearLayout = view.native_ad_inside_layout
var attributionView: TextView = view.native_ad_attribution
var headlineView: TextView = view.ad_headline
var callToActionView: Button = view.ad_call_to_action
var iconView: ImageView = view.ad_app_icon
}
Code of onBindViewHolder:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = mValues[position]
if (item.nativeAd == null) {
return
}
if (item.nativeAd!!.headline == null) {
return
}
holder.attributionView.setVisibility(View.VISIBLE);
holder.insideLayoutView.setVisibility(View.VISIBLE);
holder.headlineView.text = item.nativeAd!!.headline
if (item.nativeAd!!.callToAction == null) {
holder.callToActionView.visibility = View.INVISIBLE
} else {
holder.callToActionView.visibility = View.VISIBLE
(holder.callToActionView as Button).text = item.nativeAd!!.callToAction
}
if (item.nativeAd!!.icon == null) {
holder.iconView.visibility = View.GONE
} else {
(holder.iconView as ImageView).setImageDrawable(item.nativeAd!!.icon.drawable)
holder.iconView.visibility = View.VISIBLE
}
// Assign native ad object to the native view.
holder.adView.setNativeAd(item.nativeAd!!)
}
And this is where I call adLoader. I call it in the background using BroadcastReceiver:
fun loadNativeAds(context: Context, listener: MyTripsContent.ContentEventsListener?) {
if (!adList.isEmpty()) {
return
}
try {
var unitId: String? = ""
lateinit var adLoader: AdLoader
//test key
unitId = "ca-app-pub-3940256099942544/2247696110"
adLoader = AdLoader.Builder(context, unitId)
.forUnifiedNativeAd { ad: UnifiedNativeAd ->
// Show the ad.
adList.add(ad)
if (adList.size == 5) {
listener?.onLoadedDocuments(0)
}
}
.withAdListener(object : AdListener() {
override fun onAdFailedToLoad(errorCode: Int) {
// Handle the failure by logging, altering the UI, and so on.
if (!adLoader.isLoading) {
}
}
override fun onAdClicked() {
super.onAdClicked()
}
})
.withNativeAdOptions(
NativeAdOptions.Builder()
// Methods in the NativeAdOptions.Builder class can be
// used here to specify individual options settings.
.build()
)
.build()
adLoader.loadAds(AdRequest.Builder().build(), 5)
} catch (exception: Exception) {
exception.printStackTrace()
}
}
So as I mentioned ads work well but they are not clickable. I'm not sure if this is a bug from admob, or my code or something I am missing. I think other developers will face the same issue in the future, so it would be good to solve it. Thank you in advance.
So due to lack of detailed documentation and examples I found I was missing one line of code. Many other examples do not have this line also. I only added one line in onBindViewHolder
From this:
if (item.nativeAd!!.callToAction == null) {
holder.callToActionView.visibility = View.INVISIBLE
} else {
holder.callToActionView.visibility = View.VISIBLE
(holder.callToActionView as Button).text = item.nativeAd!!.callToAction
}
to this:
if (item.nativeAd!!.callToAction == null) {
holder.callToActionView.visibility = View.INVISIBLE
} else {
holder.callToActionView.visibility = View.VISIBLE
(holder.callToActionView as Button).text = item.nativeAd!!.callToAction
holder.adView.callToActionView = (holder.callToActionView as Button)
}
That means I needed to attach my button as callToActionView