java - 如何在 Xamarin.Android 中实现 RewardedAdLoadCallback?

标签 java c# android xamarin admob

我正在尝试在 C# 中的 Xamarin.Android 中实现奖励广告。
Android 文档中的代码 fragment 是用 Java 编写的,通常我在 C# 中采用该代码没有太大问题,但现在看来确实是个问题。
要在 Java 中加载 RewardedAd,您必须执行以下操作 (according to the official documentation):

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# 中无法做到这一点。
所以我的解决方案是创建自己的类(class),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
我尝试在 Internet 上搜索此错误并得出结论,这是一个 Java 错误并且与泛型类型有关(请参阅 this SO 问题)。但是,我在我的代码和关于奖励广告的 Android 文档中都没有看到任何通用类型。关于我正在尝试实现的奖励广告的 Xamarin 文档也为零。
如果有人能帮我解决这个问题,我会很高兴。提前致谢。

最佳答案

这是让插页式广告和奖励广告在 Xamarin.GooglePlayServices.Ads 版本 120.0.0 中工作的技巧。
将以下文件添加到您的项目(需要使用 unsafe 标志构建)并使用 Android.Gms.Ads.Hack命名空间来加载你的广告和子类你的回调。
例如,InterstitialAd.Load变成 global::Android.Gms.Ads.Hack.InterstitialAd.LoadInterstitialAdLoadCallback变成 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)
        {
        }
    }
}

关于java - 如何在 Xamarin.Android 中实现 RewardedAdLoadCallback?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66232638/

相关文章:

java - 启用/禁用 beta/未完成代码的策略和模式

C#:托管 Windows 服务

c# - 如何将项目从一个 DropDownList 复制到另一个

android - onTouchEvent() 是否必须从 MapView 扩展?

java - 是否可以从内存中获取所有对象?

java - 选择 nlp api (java)

android - 是否可以以编程方式确定 Android 设备是否已 root?

Android Studio 找不到 com.android.tools.build :grade:2. 10

使用SQL的Java登录程序

c# - 在 C# 中对对象列表进行排序的算法