I am implementing native ads in React native. I am loading ads via Native module method therefore I wrote my code in android and return the view to react native layer. The ads are loading fine at react native side but only the media element which loads the video is coming blank. I am unable to figure out the reason, is it version compatibility issue. I am using the following version:-
React native - 0.72.8
Google ads version at android native side - com.google.android.gms:play-services-ads:22.0.0
NativeAdViewManager.java
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.nativead.MediaView;
import com.google.android.gms.ads.nativead.NativeAdOptions;
import com.google.android.gms.ads.nativead.NativeAdView;
import com.google.android.gms.ads.nativead.VideoOptions;
public class NativeAdViewManager extends SimpleViewManager<View> {
private static final String REACT_CLASS = "NativeAdView";
private final ReactApplicationContext reactContext;
private String adUnitId = "/21775744923/example/native-video"; // Test video ad unit ID
private boolean startMuted = true;
public NativeAdViewManager(ReactApplicationContext reactContext) {
this.reactContext = reactContext;
}
@NonNull
@Override
public String getName() {
return REACT_CLASS;
}
@NonNull
@Override
protected View createViewInstance(@NonNull ThemedReactContext themedReactContext) {
// Create the ad container view
LinearLayout adContainer = new LinearLayout(themedReactContext);
adContainer.setOrientation(LinearLayout.VERTICAL);
// Inflate your native ad layout
View adView = LayoutInflater.from(themedReactContext).inflate(R.layout.native_video_ad_layout, adContainer, false);
adContainer.addView(adView);
// Load the native video ad
loadNativeVideoAd(adView);
return adContainer;
}
@ReactProp(name = "adUnitId")
public void setAdUnitId(View view, String adUnitId) {
this.adUnitId = adUnitId;
// Reload the ad with new ad unit ID
// loadNativeVideoAd(view.findViewById(R.id.native_ad_view));
}
@ReactProp(name = "startMuted")
public void setStartMuted(View view, boolean startMuted) {
this.startMuted = startMuted;
// Reload the ad with new mute setting
// loadNativeVideoAd(view.findViewById(R.id.native_ad_view));
}
private void loadNativeVideoAd(View view) {
final NativeAdView adView = view.findViewById(R.id.native_ad_view);
// Create video options - this is the key difference for video ads
VideoOptions videoOptions = new VideoOptions.Builder()
.setStartMuted(startMuted)
.build();
// Create native ad options with video options
NativeAdOptions adOptions = new NativeAdOptions.Builder()
.setVideoOptions(videoOptions)
.build();
AdLoader adLoader = new AdLoader.Builder(reactContext, adUnitId)
.forNativeAd(nativeAd -> {
// Set the media view - this will display the video content
MediaView mediaView = adView.findViewById(R.id.ad_media);
if (nativeAd.getMediaContent() != null) {
mediaView.setMediaContent(nativeAd.getMediaContent());
adView.setMediaView(mediaView);
mediaView.setVisibility(View.VISIBLE);
System.out.println("MediaView visibility after setVisible: " + mediaView.getVisibility());
System.out.println("MediaView width: " + mediaView.getWidth() + ", height: " + mediaView.getHeight());
// Force layout measurement
mediaView.requestLayout();
adView.requestLayout();
}
// else{
// mediaView.setVisibility(View.GONE);
// }
// Set headline
TextView headlineView = adView.findViewById(R.id.ad_headline);
headlineView.setText(nativeAd.getHeadline());
adView.setHeadlineView(headlineView);
// Set body text
TextView bodyView = adView.findViewById(R.id.ad_body);
if (nativeAd.getBody() != null) {
System.out.println("Hello " + nativeAd.getBody());
bodyView.setText(nativeAd.getBody());
bodyView.setVisibility(View.VISIBLE);
} else {
bodyView.setVisibility(View.GONE);
}
adView.setBodyView(bodyView);
// Set call to action
Button callToActionView = adView.findViewById(R.id.ad_call_to_action);
if (nativeAd.getCallToAction() != null) {
callToActionView.setText(nativeAd.getCallToAction());
callToActionView.setVisibility(View.VISIBLE);
} else {
callToActionView.setVisibility(View.GONE);
}
adView.setCallToActionView(callToActionView);
// Set icon
ImageView iconView = adView.findViewById(R.id.ad_icon);
if (nativeAd.getIcon() != null) {
System.out.println("Hello there " + nativeAd.getIcon());
System.out.println("Hello there body : : " + nativeAd.getBody());
System.out.println("Hello there video" + nativeAd.getMediaContent().hasVideoContent());
System.out.println("Hello there" + nativeAd.getMediaContent().getDuration());
System.out.println("Hello there imagemedia" + nativeAd.getMediaContent().getMainImage());
iconView.setImageDrawable(nativeAd.getIcon().getDrawable());
iconView.setVisibility(View.VISIBLE);
} else {
iconView.setVisibility(View.GONE);
}
adView.setIconView(iconView);
// Set advertiser name
TextView advertiserView = adView.findViewById(R.id.ad_advertiser);
if (nativeAd.getAdvertiser() != null) {
advertiserView.setText(nativeAd.getAdvertiser());
advertiserView.setVisibility(View.VISIBLE);
} else {
advertiserView.setVisibility(View.GONE);
}
adView.setAdvertiserView(advertiserView);
// Register the native ad object
adView.setNativeAd(nativeAd);
// Make the ad visible
adView.setVisibility(View.VISIBLE);
})
.withAdListener(new AdListener() {
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
// Handle ad loading failure
System.out.println("Ad failed to load: " + loadAdError.getMessage());
System.out.println("Code: " + loadAdError.getCode());
System.out.println("Domain: " + loadAdError.getDomain());
System.out.println("Cause: " + loadAdError.getCause());
System.out.println("Response Info: " + loadAdError.getResponseInfo());
}
@Override
public void onAdLoaded() {
System.out.println("Native video ad loaded successfully");
}
})
.withNativeAdOptions(adOptions) // Set the native ad options with video options
.build();
adLoader.loadAd(new AdRequest.Builder().build());
}
}
------------------------ native_video_ad_layout.xml --------------------------
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/native_ad_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_icon"
android:layout_width="48dp"
android:layout_height="39dp"
android:adjustViewBounds="true"
android:paddingEnd="5dp"
android:contentDescription="@string/ad_icon_description" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#0000FF"
android:textSize="26sp"
android:textStyle="bold" />
<TextView
android:id="@+id/ad_advertiser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/ad_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="5dp"
android:textSize="12sp" />
<TextView
android:id="@+id/ad_store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
<RatingBar
android:id="@+id/ad_stars"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#0000FF"
android:textSize="12sp" />
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:visibility="visible"
android:layout_marginBottom="20dp" />
<Button
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="#4CAF50"
android:textColor="@android:color/white" />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>