我该如何在Xamarin.Android中实现RewardedAdLoadCallback?

4

我正在尝试在C#中的Xamarin.Android实现激励广告。

Android文档中的代码片段是用Java编写的,通常我没有太多问题在C#中采用该代码,但现在似乎有些问题。

要在Java中加载RewardedAd,您需要按照以下步骤进行操作(根据官方文档):

AdRequest adRequest = new AdRequest.Builder().build();

RewardedAd.load(this, "ca-app-pub-3940256099942544/5224354917",
      adRequest, new RewardedAdLoadCallback(){
        @Override
        public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
          // Handle the error.
          Log.d(TAG, loadAdError.getMessage());
          mRewardedAd = null
        }

        @Override
        public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
          mRewardedAd = rewardedAd;
          Log.d(TAG, "onAdFailedToLoad");
        }
    });

现在问题在于,此代码中传递的对象 RewardedAdLoadCallback 也定义了方法实现 (onAdFailedToLoadonAdLoaded),但在 C# 中无法这样做。

因此,我的解决方案是创建自己的类 MyRewardedAdLoadCallback 并覆盖这些方法。

public class MyRewardedAdLoadCallback : RewardedAdLoadCallback
{
    public override void OnAdLoaded(Java.Lang.Object p0)
    {
        base.OnAdLoaded(p0);
    }

    public override void OnAdFailedToLoad(LoadAdError p0)
    {
        base.OnAdFailedToLoad(p0);
    }
}

然后我使用以下代码简单地加载激励式广告:

AdRequest adRequest = new AdRequest.Builder().Build();

RewardedAd.Load(this, "ca-app-pub-3940256099942544/5224354917", adRequest, new MyRewardedAdLoadCallback());

现在出现了一个奇怪的错误,当我构建项目时会出现这个错误:

error: name clash: onAdLoaded(Object) in MyRewardedAdLoadCallback and onAdLoaded(AdT) in AdLoadCallback have the same erasure, yet neither overrides the other
    public void onAdLoaded (java.lang.Object p0)
  where AdT is a type-variable:
    AdT extends Object declared in class AdLoadCallback

我尝试在互联网上搜索此错误,并得出结论,这是一个Java错误,与通用类型有关(请参见此SO问题)。然而,在我的代码中没有看到任何通用类型,在Android奖励广告的文档中也没有。同时,我正在尝试实现的奖励广告没有任何Xamarin文档。
如果有人能帮忙解决这个问题,我将非常感激。提前谢谢。

你尝试重写了OnRewardedAdLoaded和OnRewardedAdFailedToLoad方法吗? - Leo Zhu
@LeoZhu-MSFT 覆盖这两个方法完全没有问题,但它们自 SDK 版本 19.7.0 起已被弃用,因此我不想使用它们。 - parhine
我刚刚发现这是一个已知问题,只在10天前被添加。我猜我只能等待修复并在此期间使用弃用的版本。 - parhine
遇到了同样的问题。更糟糕的是,我的广告已经停止加载一个星期了,一直显示“无填充”。 - Maximus
1
@Maximus 听起来真的很糟糕。在我之前的评论中发送的 Github 链接中有一个带有非官方解决方案的评论(链接)。不过我自己还没有尝试过。 - parhine
显示剩余2条评论
3个回答

0
public abstract class InterstitialCallback : Android.Gms.Ads.Interstitial.InterstitialAdLoadCallback
{
    [Register("onAdLoaded", "(Lcom/google/android/gms/ads/interstitial/InterstitialAd;)V", "GetOnAdLoadedHandler")]
    public virtual void OnAdLoaded(Android.Gms.Ads.Interstitial.InterstitialAd interstitialAd)
    {
    }

    private static Delegate cb_onAdLoaded;
    private static Delegate GetOnAdLoadedHandler()
    {
        if (cb_onAdLoaded is null)
            cb_onAdLoaded = JNINativeWrapper.CreateDelegate((Action<IntPtr, IntPtr, IntPtr>)n_onAdLoaded);
        return cb_onAdLoaded;
    }
    private static void n_onAdLoaded(IntPtr jnienv, IntPtr native__this, IntPtr native_p0)
    {
        InterstitialCallback thisobject = GetObject<InterstitialCallback>(jnienv, native__this, JniHandleOwnership.DoNotTransfer);
        Android.Gms.Ads.Interstitial.InterstitialAd resultobject = GetObject<Android.Gms.Ads.Interstitial.InterstitialAd>(native_p0, JniHandleOwnership.DoNotTransfer);
        thisobject.OnAdLoaded(resultobject);
    }
}
public abstract class RewardedAdLoadCallback : Android.Gms.Ads.Rewarded.RewardedAdLoadCallback
{
    [Register("onAdLoaded", "(Lcom/google/android/gms/ads/rewarded/RewardedAd;)V", "GetOnAdLoadedHandler")]
    public virtual void OnAdLoaded(Android.Gms.Ads.Rewarded.RewardedAd rewardedAd)
    {
    }

    private static Delegate cb_onAdLoaded;
    private static Delegate GetOnAdLoadedHandler()
    {
        if (cb_onAdLoaded is null)
        {
            cb_onAdLoaded = JNINativeWrapper.CreateDelegate((Action<IntPtr, IntPtr, IntPtr>)n_onAdLoaded);
        }

        return cb_onAdLoaded;
    }
    private static void n_onAdLoaded(IntPtr jnienv, IntPtr native__this, IntPtr native_p0)
    {
        RewardedAdLoadCallback thisobject = GetObject<RewardedAdLoadCallback>(jnienv, native__this, JniHandleOwnership.DoNotTransfer);
        Android.Gms.Ads.Rewarded.RewardedAd resultobject = GetObject<Android.Gms.Ads.Rewarded.RewardedAd>(native_p0, JniHandleOwnership.DoNotTransfer);
        thisobject.OnAdLoaded(resultobject);
    }
}

0

或许只需要子类化回调函数

class RewardedVideoAds : RewardedAdLoadCallback
    {
        private RewardedAd rewardedAd;

        
        public RewardedVideoAds()
        {
            
            AdRequest adRequest = new AdRequest.Builder().Build();
           
            RewardedAd.Load(MainActivity.Current, "ca-app-pub-3940256099942544/5224354917", adRequest, this);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }
        public override void OnAdLoaded(Java.Lang.Object p0)
        {
            base.OnAdLoaded(p0);
        }
    }

0

这里有一个小技巧,可以让Interstitial和Rewarded广告在Xamarin.GooglePlayServices.Ads版本120.0.0中同时工作。

将以下文件添加到您的项目中(需要使用不安全标志进行构建),并使用Android.Gms.Ads.Hack命名空间来加载广告和子类化回调。

例如,InterstitialAd.Load变成了global::Android.Gms.Ads.Hack.InterstitialAd.Load,而InterstitialAdLoadCallback则变成了global::Android.Gms.Ads.Hack.InterstitialAdLoadCallback

回调类为插页式广告和激励广告加载回调添加了OnInterstitialAdLoaded()OnRewardedAdLoaded()虚拟方法。

using System;
using System.ComponentModel;
using System.Diagnostics;
using Android.Content;
using Android.Runtime;
using Java.Interop;

namespace Android.Gms.Ads.Hack
{
    public abstract class InterstitialAd : Java.Lang.Object
    {
        private static readonly JniPeerMembers _members = new XAPeerMembers("com/google/android/gms/ads/interstitial/InterstitialAd", typeof(InterstitialAd));

        public unsafe static void Load(Context context, string adUnit, AdRequest request, AdLoadCallback callback)
        {
            IntPtr intPtr = JNIEnv.NewString(adUnit);
            try
            {
                JniArgumentValue* ptr = stackalloc JniArgumentValue[4];
                *ptr = new JniArgumentValue(context?.Handle ?? IntPtr.Zero);
                ptr[1] = new JniArgumentValue(intPtr);
                ptr[2] = new JniArgumentValue(request?.Handle ?? IntPtr.Zero);
                ptr[3] = new JniArgumentValue(callback?.Handle ?? IntPtr.Zero);
                _members.StaticMethods.InvokeVoidMethod("load.(Landroid/content/Context;Ljava/lang/String;Lcom/google/android/gms/ads/AdRequest;Lcom/google/android/gms/ads/interstitial/InterstitialAdLoadCallback;)V", ptr);
            }
            finally
            {
                JNIEnv.DeleteLocalRef(intPtr);
                GC.KeepAlive(context);
                GC.KeepAlive(request);
                GC.KeepAlive(callback);
            }
        }
    }

    [Register("com/google/android/gms/ads/interstitial/InterstitialAdLoadCallback", DoNotGenerateAcw = true)]
    public abstract class InterstitialAdLoadCallback : AdLoadCallback
    {
        private static readonly JniPeerMembers _members = new XAPeerMembers("com/google/android/gms/ads/interstitial/InterstitialAdLoadCallback", typeof(InterstitialAdLoadCallback));

        static IntPtr class_ref => _members.JniPeerType.PeerReference.Handle;

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override JniPeerMembers JniPeerMembers => _members;

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected override IntPtr ThresholdClass => _members.JniPeerType.PeerReference.Handle;

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected override Type ThresholdType => _members.ManagedPeerType;

        protected InterstitialAdLoadCallback(IntPtr javaReference, JniHandleOwnership transfer)
            : base(javaReference, transfer)
        {
        }

        [Register(".ctor", "()V", "")]
        public unsafe InterstitialAdLoadCallback()
            : base(IntPtr.Zero, JniHandleOwnership.DoNotTransfer)
        {
            if (!(base.Handle != IntPtr.Zero))
            {
                SetHandle(_members.InstanceMethods.StartCreateInstance("()V", GetType(), null).Handle, JniHandleOwnership.TransferLocalRef);
                _members.InstanceMethods.FinishCreateInstance("()V", this, null);
            }
        }

        private static Delegate cb_onAdLoaded;

        private static Delegate GetOnAdLoadedHandler()
        {
            if (cb_onAdLoaded is null)
            {
                cb_onAdLoaded = JNINativeWrapper.CreateDelegate((Action<IntPtr, IntPtr, IntPtr>)n_onAdLoaded);
            }

            return cb_onAdLoaded;
        }

        private static void n_onAdLoaded(IntPtr jnienv, IntPtr native__this, IntPtr native_p0)
        {
            InterstitialAdLoadCallback? @object = Java.Lang.Object.GetObject<InterstitialAdLoadCallback>(jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            global::Android.Gms.Ads.Interstitial.InterstitialAd object2 = Java.Lang.Object.GetObject<global::Android.Gms.Ads.Interstitial.InterstitialAd>(native_p0, JniHandleOwnership.DoNotTransfer);
            @object!.OnInterstitialAdLoaded(object2);
        }

        [Register("onAdLoaded", "(Lcom/google/android/gms/ads/interstitial/InterstitialAd;)V", "GetOnAdLoadedHandler")]
        public virtual void OnInterstitialAdLoaded(global::Android.Gms.Ads.Interstitial.InterstitialAd interstitialAd)
        {
        }
    }

    public abstract class RewardedAd : Java.Lang.Object
    {
        private static readonly JniPeerMembers _members = new XAPeerMembers("com/google/android/gms/ads/rewarded/RewardedAd", typeof(RewardedAd));

        public unsafe static void Load(Context context, string adUnit, AdRequest request, RewardedAdLoadCallback callback)
        {
            IntPtr intPtr = JNIEnv.NewString(adUnit);
            try
            {
                JniArgumentValue* ptr = stackalloc JniArgumentValue[4];
                *ptr = new JniArgumentValue(context?.Handle ?? IntPtr.Zero);
                ptr[1] = new JniArgumentValue(intPtr);
                ptr[2] = new JniArgumentValue(request?.Handle ?? IntPtr.Zero);
                ptr[3] = new JniArgumentValue(callback?.Handle ?? IntPtr.Zero);
                _members.StaticMethods.InvokeVoidMethod("load.(Landroid/content/Context;Ljava/lang/String;Lcom/google/android/gms/ads/AdRequest;Lcom/google/android/gms/ads/rewarded/RewardedAdLoadCallback;)V", ptr);
            }
            finally
            {
                JNIEnv.DeleteLocalRef(intPtr);
                GC.KeepAlive(context);
                GC.KeepAlive(request);
                GC.KeepAlive(callback);
            }
        }
    }

    [Register("com/google/android/gms/ads/rewarded/RewardedAdLoadCallback", DoNotGenerateAcw = true)]
    public abstract class RewardedAdLoadCallback : AdLoadCallback
    {
        private static readonly JniPeerMembers _members = new XAPeerMembers("com/google/android/gms/ads/rewarded/RewardedAdLoadCallback", typeof(RewardedAdLoadCallback));

        static IntPtr class_ref => _members.JniPeerType.PeerReference.Handle;

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override JniPeerMembers JniPeerMembers => _members;

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected override IntPtr ThresholdClass => _members.JniPeerType.PeerReference.Handle;

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected override Type ThresholdType => _members.ManagedPeerType;

        protected RewardedAdLoadCallback(IntPtr javaReference, JniHandleOwnership transfer)
            : base(javaReference, transfer)
        {
        }

        [Register(".ctor", "()V", "")]
        public unsafe RewardedAdLoadCallback()
            : base(IntPtr.Zero, JniHandleOwnership.DoNotTransfer)
        {
            if (!(base.Handle != IntPtr.Zero))
            {
                SetHandle(_members.InstanceMethods.StartCreateInstance("()V", GetType(), null).Handle, JniHandleOwnership.TransferLocalRef);
                _members.InstanceMethods.FinishCreateInstance("()V", this, null);
            }
        }

        private static Delegate cb_onAdLoaded;

        private static Delegate GetOnAdLoadedHandler()
        {
            if (cb_onAdLoaded is null)
            {
                cb_onAdLoaded = JNINativeWrapper.CreateDelegate((Action<IntPtr, IntPtr, IntPtr>)n_onAdLoaded);
            }

            return cb_onAdLoaded;
        }

        private static void n_onAdLoaded(IntPtr jnienv, IntPtr native__this, IntPtr native_p0)
        {
            RewardedAdLoadCallback? @object = Java.Lang.Object.GetObject<RewardedAdLoadCallback>(jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            global::Android.Gms.Ads.Rewarded.RewardedAd object2 = Java.Lang.Object.GetObject<global::Android.Gms.Ads.Rewarded.RewardedAd>(native_p0, JniHandleOwnership.DoNotTransfer);
            @object!.OnRewardedAdLoaded(object2);
        }

        [Register("onAdLoaded", "(Lcom/google/android/gms/ads/rewarded/RewardedAd;)V", "GetOnAdLoadedHandler")]
        public virtual void OnRewardedAdLoaded(global::Android.Gms.Ads.Rewarded.RewardedAd rewardedAd)
        {
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接