简体   繁体   中英

Google AdMob advertisement correctly sized, but blank, in Android “native component” using React-Native

I'm trying to display a Google AdMob advertisement in a React-Native "native component" on Android. The logs seem to indicate success, but I don't see the advertisement; all I see is a blank space where the advertisement should be.

Interestingly if I change the size of the advertisement from BANNER to MEDIUM_RECTANGLE I can see that the blank space changes size, which means the advertisement is in some sense "there", it's just not showing anything.

Specifically, this is the React-Native "native component" for the view:

package com.Experiment123;
import com.facebook.react.uimanager.ThemedReactContext;

import android.os.Bundle;
import android.widget.LinearLayout;
import android.util.Log;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.MobileAds;

class Experiment123AdView extends LinearLayout
{
    public Experiment123AdView(ThemedReactContext context)
    {
        super(context.getBaseContext());
        Log.d("Experiment123AdView", "Attempt-2");
        MobileAds.initialize(context, "ca-app-pub-3940256099942544~3347511713");
        inflate(getContext(), R.layout.experiment123admoblayout, this);

        AdView mAdView = (AdView)(findViewById(R.id.ad_view));
        AdRequest adRequest = new AdRequest.Builder()
                .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                .build();
        mAdView.loadAd(adRequest);
    }
}

And this is the XML for the layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello"
        android:textColor="@android:color/holo_orange_dark" />

    <com.google.android.gms.ads.AdView
        xmlns:ads="http://schemas.android.com/apk/res-auto"
        android:id="@+id/ad_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        ads:adSize="MEDIUM_RECTANGLE"
        ads:adUnitId="ca-app-pub-3940256099942544/6300978111" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Goodbye"
        android:textColor="@android:color/holo_orange_dark" />

</LinearLayout>

At runtime, I see this in the logcat:

grep "Ads   " logs.txt 
11-25 18:41:32.555 19534 19534 I Ads     : Starting ad request.
11-25 18:41:32.559 19534 19534 I Ads     : This request is sent from a test device.
11-25 18:41:32.652 19534 19622 W Ads     : Google Play Service is out of date, the Google Mobile Ads SDK will not integrate with Firebase. Admob/Firebase integration requires updated Google Play Service.
11-25 18:41:36.337 19534 19534 I Ads     : Scheduling ad refresh 60000 milliseconds from now.
11-25 18:41:36.391 19534 19534 I Ads     : Ad finished loading.

which would seem to suggest something good happened... but in the application all I see is this:

在此处输入图片说明

No advertisement is visible between the "Hello" and the "Goodbye".

When I change the adSize from MEDIUM_RECTANGLE to BANNER the blank space between Hello and Goodbye shrinks accordingly:

在此处输入图片说明

I've tried putting various combinations of INTERNET , SYSTEM_ALERT_WINDOW , ACCESS_NETWORK_STATE , READ_PHONE_STATE permissions in the manifest... but it makes no difference. It also makes no difference if I run in the emulator or a real device.

Does anyone know why the advertisement is not visible?

That seems like an emulator. If I remember correctly, ads do not get served in an emulator. Try in a real device.

I believe my original problem was a result of not having av.measure(widthInPixels, heightInPixels); and av.layout(left, top, left + widthInPixels, top + heightInPixels); in the onAdLoaded listener.

The following seems to be the most minimal working thing that solves my original problem:

package com.Experiment123;

import android.util.Log;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.views.view.ReactViewGroup;
import com.google.android.gms.ads.*;
import java.util.List;
import java.util.Collections;
import java.util.Arrays;

class Experiment123AdManager
        extends SimpleViewManager<ReactViewGroup> {
    @Override
    public String getName() {
        return "Experiment123Ad";
    }

    @Override
    protected ReactViewGroup createViewInstance(ThemedReactContext themedReactContext) {
        Log.d("Experiment123AdManager", "createViewInstance(ThemedReactContext themedReactContext)");
        final ThemedReactContext ctx = themedReactContext;
        final ReactViewGroup rvg = new ReactViewGroup(ctx);
        final AdView av = new AdView(ctx);
        rvg.addView(av);
        av.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() {
                Log.d("Experiment123AdManager", "onAdLoaded()");
                int widthInPixels = av.getAdSize().getWidthInPixels(ctx);
                int heightInPixels = av.getAdSize().getHeightInPixels(ctx);
                int left = ((rvg.getWidth() - widthInPixels) / 2);
                int top = ((rvg.getHeight() - heightInPixels) / 2);
                if(left < 0) left = 0;
                if(top < 0) top = 0;
                av.measure(widthInPixels, heightInPixels);
                av.layout(left, top, left + widthInPixels, top + heightInPixels);
            }
        });
        av.setAdUnitId("ca-app-pub-3940256099942544/6300978111");
        av.setAdSize(AdSize.MEDIUM_RECTANGLE);
        av.loadAd(new AdRequest.Builder().build());
        return rvg;
    }
}

public class Experiment123AdPackage implements ReactPackage {

    @Override
    public List<NativeModule>
    createNativeModules(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override public List<ViewManager>
    createViewManagers(ReactApplicationContext reactContext)
    {
        Log.d("Experiment123AdPackage", "createViewManagers(ReactApplicationContext reactContext)");
        return Arrays.<ViewManager>asList( new Experiment123AdManager() );
    }
}

Don't forget to add the following to the MainActivity class (that React Native generates):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM