GooglePlayServicesComponents icon indicating copy to clipboard operation
GooglePlayServicesComponents copied to clipboard

Name Clash in InterstitialAdLoadCallback and RewardedAdLoadCallback

Open BilKaz opened this issue 4 years ago • 31 comments

Operating System & Version (eg: Mac OSX 10.11):

Build Version: Android 11

Google Play Services Version

Xamarin.GooglePlayServices.Ads : 119.7.0

Describe your Issue

I am observing a name clash in the override method OnAdLoaded(Java.Lang.Object p0) for both the callbacks of Interstitial and Rewarded Ads for my Android App using Xamarin.Android.

It seems the base class is deriving from AdLoadCallback instead of InterstitialAdLoadCallback/RewardedAdLoadCallback

public class InterstitialCallback : Android.Gms.Ads.Interstitial.InterstitialAdLoadCallback
        {
            GameActivity context;

            public InterstitialCallback(GameActivity _context)
            {
                context = _context;
            }

            public override void OnAdLoaded(Java.Lang.Object p0)
            {
                Log.Debug("Google-Ads", "I_Ad Loaded");
                context.interstitialAd = (Android.Gms.Ads.Interstitial.InterstitialAd)p0;
                base.OnAdLoaded(p0);
            }

            public override void OnAdFailedToLoad(LoadAdError p0)
            {
                Log.Debug("Google-Ads", "I_Ad Load Failed: " + p0.Message);
                context.interstitialAd = null;
                base.OnAdFailedToLoad(p0);
            }
        }

Include any relevant Exception Stack traces, build logs, adb logs:

obj\Debug\110\android\src\crc646102153de932c4e0\AdMob_InterstitialCallback.java:35: error: name clash: onAdLoaded(Object) in AdMob_InterstitialCallback and onAdLoaded(AdT) in AdLoadCallback have the same erasure, yet neither overrides the other
1>  	public void onAdLoaded (java.lang.Object p0)
1>  	            ^
1>    where AdT is a type-variable:
1>      AdT extends Object declared in class AdLoadCallback
1>  Note: Some input files use or override a deprecated API.
1>  Note: Recompile with -Xlint:deprecation for details.
1>  Note: Some input files use unchecked or unsafe operations.
1>  Note: Recompile with -Xlint:unchecked for details.
1>  1 error

BilKaz avatar Feb 07 '21 08:02 BilKaz

I can confirm the issue.

Mataboge avatar Feb 13 '21 00:02 Mataboge

I can confirm the issue.

Yes, same here!

simonsymhoven avatar Feb 13 '21 06:02 simonsymhoven

Same here!

TomasHadraba avatar Feb 18 '21 22:02 TomasHadraba

Thanks for the feedback.

Can you provide minimal repro sample, please?

moljac avatar Feb 19 '21 13:02 moljac

Yes indeed there is the problem , 119.7.0 version its not that stable !! if you cant wait for the official solution you can do this :

 public class InterstitialCallback : Android.Gms.Ads.AdLoadCallback
    {
        public override void OnAdLoaded(Java.Lang.Object p0)
        {
            base.OnAdLoaded(p0);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }


        public static void LaodInterstitial(Android.Content.Context context, string Adunit, Android.Gms.Ads.AdRequest adRequest, Android.Gms.Ads.AdLoadCallback Callback)
        {
            IntPtr AdRequestClass = JNIEnv.GetObjectClass(adRequest.Handle);
            IntPtr zzdsmethodID = JNIEnv.GetMethodID(AdRequestClass, "zzds", "()Lcom/google/android/gms/internal/ads/zzzk;");
            Java.Lang.Object zzzk = GetObject<Java.Lang.Object>(JNIEnv.CallObjectMethod(adRequest.Handle, zzdsmethodID), JniHandleOwnership.TransferLocalRef);

            IntPtr zzakjtype = JNIEnv.FindClass("com/google/android/gms/internal/ads/zzakj");
            IntPtr zzakjConstructor = JNIEnv.GetMethodID(zzakjtype, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V");
            IntPtr zzakjInstance = JNIEnv.NewObject(zzakjtype, zzakjConstructor, new JValue[] { new JValue(context), new JValue(new Java.Lang.String(Adunit)) });

            IntPtr LoadMethodId = JNIEnv.GetMethodID(zzakjtype, "zza", "(Lcom/google/android/gms/internal/ads/zzzk;Lcom/google/android/gms/ads/AdLoadCallback;)V");
            JNIEnv.CallVoidMethod(zzakjInstance, LoadMethodId, new JValue[] { new JValue(zzzk), new JValue(Callback) });
        }
    }

Make the InterstitialCallback inherit directly from " Android.Gms.Ads.AdLoadCallback" , then load the ad with the method above ; its exactly what the regular Load method do , but in a uglier way .

YoussefR33 avatar Feb 21 '21 03:02 YoussefR33

Yes indeed there is the problem , 119.7.0 version its not that stable !! if you cant wait for the official solution you can do this :

 public class InterstitialCallback : Android.Gms.Ads.AdLoadCallback
    {
        public override void OnAdLoaded(Java.Lang.Object p0)
        {
            base.OnAdLoaded(p0);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }


        public static void LaodInterstitial(Android.Content.Context context, string Adunit, Android.Gms.Ads.AdRequest adRequest, Android.Gms.Ads.AdLoadCallback Callback)
        {
            IntPtr AdRequestClass = JNIEnv.GetObjectClass(adRequest.Handle);
            IntPtr zzdsmethodID = JNIEnv.GetMethodID(AdRequestClass, "zzds", "()Lcom/google/android/gms/internal/ads/zzzk;");
            Java.Lang.Object zzzk = GetObject<Java.Lang.Object>(JNIEnv.CallObjectMethod(adRequest.Handle, zzdsmethodID), JniHandleOwnership.TransferLocalRef);

            IntPtr zzakjtype = JNIEnv.FindClass("com/google/android/gms/internal/ads/zzakj");
            IntPtr zzakjConstructor = JNIEnv.GetMethodID(zzakjtype, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V");
            IntPtr zzakjInstance = JNIEnv.NewObject(zzakjtype, zzakjConstructor, new JValue[] { new JValue(context), new JValue(new Java.Lang.String(Adunit)) });

            IntPtr LoadMethodId = JNIEnv.GetMethodID(zzakjtype, "zza", "(Lcom/google/android/gms/internal/ads/zzzk;Lcom/google/android/gms/ads/AdLoadCallback;)V");
            JNIEnv.CallVoidMethod(zzakjInstance, LoadMethodId, new JValue[] { new JValue(zzzk), new JValue(Callback) });
        }
    }

Make the InterstitialCallback inherit directly from " Android.Gms.Ads.AdLoadCallback" , then load the ad with the method above ; its exactly what the regular Load method do , but in a uglier way .

Thanks alot @r33software , this helped

Mataboge avatar Feb 22 '21 17:02 Mataboge

Yes indeed there is the problem , 119.7.0 version its not that stable !! if you cant wait for the official solution you can do this :

 public class InterstitialCallback : Android.Gms.Ads.AdLoadCallback
    {
        public override void OnAdLoaded(Java.Lang.Object p0)
        {
            base.OnAdLoaded(p0);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }


        public static void LaodInterstitial(Android.Content.Context context, string Adunit, Android.Gms.Ads.AdRequest adRequest, Android.Gms.Ads.AdLoadCallback Callback)
        {
            IntPtr AdRequestClass = JNIEnv.GetObjectClass(adRequest.Handle);
            IntPtr zzdsmethodID = JNIEnv.GetMethodID(AdRequestClass, "zzds", "()Lcom/google/android/gms/internal/ads/zzzk;");
            Java.Lang.Object zzzk = GetObject<Java.Lang.Object>(JNIEnv.CallObjectMethod(adRequest.Handle, zzdsmethodID), JniHandleOwnership.TransferLocalRef);

            IntPtr zzakjtype = JNIEnv.FindClass("com/google/android/gms/internal/ads/zzakj");
            IntPtr zzakjConstructor = JNIEnv.GetMethodID(zzakjtype, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V");
            IntPtr zzakjInstance = JNIEnv.NewObject(zzakjtype, zzakjConstructor, new JValue[] { new JValue(context), new JValue(new Java.Lang.String(Adunit)) });

            IntPtr LoadMethodId = JNIEnv.GetMethodID(zzakjtype, "zza", "(Lcom/google/android/gms/internal/ads/zzzk;Lcom/google/android/gms/ads/AdLoadCallback;)V");
            JNIEnv.CallVoidMethod(zzakjInstance, LoadMethodId, new JValue[] { new JValue(zzzk), new JValue(Callback) });
        }
    }

Make the InterstitialCallback inherit directly from " Android.Gms.Ads.AdLoadCallback" , then load the ad with the method above ; its exactly what the regular Load method do , but in a uglier way .

come from google search , facing the same problem would you please share the fixed code on Rewarded AD too? thanks :)

kenchan97 avatar Mar 25 '21 16:03 kenchan97

Yes indeed there is the problem , 119.7.0 version its not that stable !! if you cant wait for the official solution you can do this :

 public class InterstitialCallback : Android.Gms.Ads.AdLoadCallback
    {
        public override void OnAdLoaded(Java.Lang.Object p0)
        {
            base.OnAdLoaded(p0);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }


        public static void LaodInterstitial(Android.Content.Context context, string Adunit, Android.Gms.Ads.AdRequest adRequest, Android.Gms.Ads.AdLoadCallback Callback)
        {
            IntPtr AdRequestClass = JNIEnv.GetObjectClass(adRequest.Handle);
            IntPtr zzdsmethodID = JNIEnv.GetMethodID(AdRequestClass, "zzds", "()Lcom/google/android/gms/internal/ads/zzzk;");
            Java.Lang.Object zzzk = GetObject<Java.Lang.Object>(JNIEnv.CallObjectMethod(adRequest.Handle, zzdsmethodID), JniHandleOwnership.TransferLocalRef);

            IntPtr zzakjtype = JNIEnv.FindClass("com/google/android/gms/internal/ads/zzakj");
            IntPtr zzakjConstructor = JNIEnv.GetMethodID(zzakjtype, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V");
            IntPtr zzakjInstance = JNIEnv.NewObject(zzakjtype, zzakjConstructor, new JValue[] { new JValue(context), new JValue(new Java.Lang.String(Adunit)) });

            IntPtr LoadMethodId = JNIEnv.GetMethodID(zzakjtype, "zza", "(Lcom/google/android/gms/internal/ads/zzzk;Lcom/google/android/gms/ads/AdLoadCallback;)V");
            JNIEnv.CallVoidMethod(zzakjInstance, LoadMethodId, new JValue[] { new JValue(zzzk), new JValue(Callback) });
        }
    }

Make the InterstitialCallback inherit directly from " Android.Gms.Ads.AdLoadCallback" , then load the ad with the method above ; its exactly what the regular Load method do , but in a uglier way .

come from google search , facing the same problem would you please share the fixed code on Rewarded AD too? thanks :)

its fine use the old way (deprecated).

YoussefR33 avatar Mar 26 '21 14:03 YoussefR33

@r33software but what about the RewardedAdLoadCallback class, it has the same problem. Is there a similar fix? I know you say use the old deprecated way, but we'll eventually need to update our code to use the new way, so we need to have it ready. Will this fix work for Rewarded too?

assassin316 avatar May 14 '21 00:05 assassin316

The Problem is now also with OpenAdListener. I updated to Ads version 120.0.0. Openads and interstitial ads wont work anymore Please fix. I will rollback

jvreeker avatar May 25 '21 13:05 jvreeker

Here's a hack to get both Interstitial and Rewarded ads working in version 120.0.0:

https://gist.github.com/dtaylorus/63fef408cec34999a1e566bd5fac27e5

Add this file to your project and use InterstitialAd.Load, InterstitialAdLoadCallback, RewardedAd.Load, and RewardedAdLoadCallback from the Android.Gms.Ads.Hack namespace (requires building with the unsafe flag).

The callback classes add OnInterstitialAdLoaded and OnRewardedAdLoaded virtual methods to the interstitial and rewarded ad load callbacks, respectively.

dtaylorus avatar May 26 '21 21:05 dtaylorus

This is so bizarre. Even after so many revisions, this issue has been ignored... I continue to have the same problem

BilKaz avatar Jun 03 '21 20:06 BilKaz

This is so bizarre. Even after so many revisions, this issue has been ignored... I continue to have the same problem

They just don't care.

hsto-code avatar Jun 10 '21 11:06 hsto-code

Here's a hack to get both Interstitial and Rewarded ads working in version 120.0.0:

https://gist.github.com/dtaylorus/63fef408cec34999a1e566bd5fac27e5

Add this file to your project and use InterstitialAd.Load, InterstitialAdLoadCallback, RewardedAd.Load, and RewardedAdLoadCallback from the Android.Gms.Ads.Hack namespace (requires building with the unsafe flag).

The callback classes add OnInterstitialAdLoaded and OnRewardedAdLoaded virtual methods to the interstitial and rewarded ad load callbacks, respectively.

I've also been dealing with this issue for a few days. This is the most practical solution so far. Thanks a lot.

thakanoduncu avatar Jun 12 '21 22:06 thakanoduncu

@dtaylorus @r33software The hack class is definitely working 👍 But how do we go ahead to call the Show method for a RewardedAd? The Load seems fine.

assassin316 avatar Jun 27 '21 02:06 assassin316

@assassin316 Use the Show method on the RewardedAd object returned in OnRewardedAdLoaded callback. The hacked callback returns a non-hacked instance of the RewardedAd object, so after you load the ad you can proceed with the non-hacked classes as you would normally.

dtaylorus avatar Jun 27 '21 12:06 dtaylorus

@thakanoduncu @dtaylorus

We are still facing this issue, am I doing something wrong ?

Android.Gms.Ads.Hack.RewardedAd.Load(Application.Context, ApplicationConstents.Instance.AdMobRewardAdUnitID, requestbuilder.Build(), rewardedAdLoadCallback);

public class RewardedAdLoadCallbackCustom : Android.Gms.Ads.Hack.RewardedAdLoadCallback
    {
        Android.Gms.Ads.Rewarded.RewardedAd rewardedAd;
        public RewardedAdLoadCallbackCustom(Android.Gms.Ads.Rewarded.RewardedAd rewardedAd)
        {
            this.rewardedAd = rewardedAd;
        }

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

            Xamarin.Forms.MessagingCenter.Send<object>(this, AppConstants.RewardAdErrorInLoading);

            IDictionary<string, string> dictinory = new Dictionary<string, string>() { { "AdFailedToLoadError", p0?.ToString() } };
            Analytics.TrackEvent(AppConstants.RewardAdErrorInLoading, dictinory);
        }

        public override void OnAdLoaded(Object p0)
        {
            base.OnAdLoaded(p0);
            rewardedAd = (Android.Gms.Ads.Rewarded.RewardedAd)p0;
            Analytics.TrackEvent(AppConstants.OnRewardedAdLoaded);
        }
    }

glintpursuit avatar Jul 03 '21 09:07 glintpursuit

@glintpursuit Override OnRewardedAdLoaded, not OnAdLoaded.

dtaylorus avatar Jul 03 '21 10:07 dtaylorus

Thanks @dtaylorus

Below is my implementation, guys please suggest improvements.

public class AdMobRewardAdsService : IAdMobReward
   {
       static Android.Gms.Ads.Rewarded.RewardedAd rewardedAd = null;

       public AdMobRewardAdsService()
       {

       }

       Action<Android.Gms.Ads.Rewarded.RewardedAd> action = (Android.Gms.Ads.Rewarded.RewardedAd ad) =>
       {
           rewardedAd = ad;
       };

       public void Load()
       {
           if (rewardedAd != null)
           {
               return;
           }

           RewardedAdLoadCallbackCustom rewardedAdLoadCallback = new RewardedAdLoadCallbackCustom(action);
           AdRequest.Builder requestbuilder = new AdRequest.Builder();

           RequestConfiguration configuration = new RequestConfiguration.Builder().SetTestDeviceIds(
                   new List<string>() {                      
                   }).Build();

           MobileAds.RequestConfiguration = configuration;

           Android.Gms.Ads.Hack.RewardedAd.Load(Application.Context, ApplicationConstents.Instance.AdMobRewardAdUnitID, requestbuilder.Build(), rewardedAdLoadCallback);
       }

       public void Show()
       {
           if (rewardedAd != null)
           {
               RewardedAdCallbackCustom rewardedAdCallbackCustom = new RewardedAdCallbackCustom();
               rewardedAd.Show(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity, rewardedAdCallbackCustom);
               rewardedAd = null;
           }
           else
           {
               Xamarin.Forms.MessagingCenter.Send<object>(this, AppConstants.RewardAdIsNotReady);
           }
       }
   }

   public class RewardedAdLoadCallbackCustom : Android.Gms.Ads.Hack.RewardedAdLoadCallback
   {
       Action<Android.Gms.Ads.Rewarded.RewardedAd> action;
       public RewardedAdLoadCallbackCustom(Action<Android.Gms.Ads.Rewarded.RewardedAd> action)
       {
           this.action = action;
       }

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

           Xamarin.Forms.MessagingCenter.Send<object>(this, AppConstants.RewardAdErrorInLoading);          
       }

       public override void OnRewardedAdLoaded(Android.Gms.Ads.Rewarded.RewardedAd rewardedAd)
       {
           base.OnAdLoaded(rewardedAd);
           this.action(rewardedAd);
       }        
   }

   public class RewardedAdCallbackCustom : Java.Lang.Object, Android.Gms.Ads.IOnUserEarnedRewardListener
   {  
       public void OnUserEarnedReward(Android.Gms.Ads.Rewarded.IRewardItem p0)
       {
           Xamarin.Forms.MessagingCenter.Send<object>(this, AppConstants.RewardAdUserRewarded);           
       }
   }

glintpursuit avatar Jul 05 '21 16:07 glintpursuit

@r33software I had an error when copying your code. Could you help me :(

android.runtime.JavaProxyThrowable: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Java.Lang.NoSuchMethodError: no non-static method "Lcom/google/android/gms/ads/AdRequest;.zzds()Lcom/google/android/gms/internal/ads/zzzk;"
[AndroidRuntime]   at Java.Interop.JniEnvironment+InstanceMethods.GetMethodID (Java.Interop.JniObjectReference type, System.String name, System.String signature) [0x0005b] in <1959115d56f8444789986cf39185638c>:0 
[AndroidRuntime]   at Android.Runtime.JNIEnv.GetMethodID (System.IntPtr kls, System.String name, System.String signature) [0x00007] in <cdf69449759145adbc699e96b2eb3764>:0 
[AndroidRuntime]   at SmartApp.Droid.MyInterstitialAdLoadCallback.LaodInterstitial (Android.Content.Context context, System.String Adunit, Android.Gms.Ads.AdRequest adRequest, Android.Gms.Ads.AdLoadCallback Callback) [0x0000d] in <5772d3fe00d941da8d02e19290d31463>:0 
[AndroidRuntime]   at AdMob.Droid.DependencyServices.AdInterstitial_Droid.LoadAd () [0x0002a] in <5772d3fe00d941da8d02e19290d31463>:0 
[AndroidRuntime]   at AdMob.Droid.DependencyServices.AdInterstitial_Droid..ctor () [0x00008] in <5772d3fe00d941da8d02e19290d31463>:0 
[AndroidRuntime]   at (wrapper managed-to-native) System.Reflection.RuntimeConstructorInfo.InternalInvoke(System.Reflection.RuntimeConstructorInfo,object,object[],System.Exception&)
[AndroidRuntime]   at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x00005] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]    --- End of inner exception stack trace ---
[AndroidRuntime]   at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x0001d] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic, System.Boolean wrapExceptions) [0x00095] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean wrapExceptions, System.Boolean skipCheckThis, System.Boolean fillCache) [0x00009] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Boolean wrapExceptions, System.Threading.StackCrawlMark& stackMark) [0x00027] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic, System.Boolean wrapExceptions) [0x00020] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) [0x00000] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at System.Activator.CreateInstance (System.Type type) [0x00000] in <98fdeeb5cad34f67b78b105df850970d>:0 
[AndroidRuntime]   at Xamarin.Forms.DependencyService.Get[T] (Xamarin.Forms.DependencyFetchTarget fetchTarget) [0x000a8] in <c35a4efef1814a57a3b6fdd7c43fccfc>:0 
[AndroidRuntime]   at SmartApp.Droid.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x000d6] in <5772d3fe00d941da8d02e19290d31463>:0 
[AndroidRuntime]   at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <cdf69449759145adbc699e96b2eb3764>:0 
[AndroidRuntime]   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.5(intptr,intptr,intptr)
[AndroidRuntime] 	at crc649f2ff61e0dedda9b.MainActivity.n_onCreate(Native Method)
[AndroidRuntime] 	at crc649f2ff61e0dedda9b.MainActivity.onCreate(MainActivity.java:38)
[AndroidRuntime] 	at android.app.Activity.performCreate(Activity.java:7183)
[AndroidRuntime] 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1221)
[AndroidRuntime] 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
[AndroidRuntime] 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
[AndroidRuntime] 	at android.app.ActivityThread.-wrap11(Unknown Source:0)
[AndroidRuntime] 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
[AndroidRuntime] 	at android.os.Handler.dispatchMessage(Handler.java:105)
[AndroidRuntime] 	at android.os.Looper.loop(Looper.java:164)
[AndroidRuntime] 	at android.app.ActivityThread.main(ActivityThread.java:6942)
[AndroidRuntime] 	at java.lang.reflect.Method.invoke(Native Method)
[AndroidRuntime] 	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
[AndroidRuntime] 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

ntminhdn avatar Jul 21 '21 12:07 ntminhdn

@ntminhdn that is the price of using internal methods of an API , names can change after new releases , this is the working version for 120.2.0

 public class InterstitialCallback : Android.Gms.Ads.AdLoadCallback
    {
        public override void OnAdLoaded(Java.Lang.Object p0)
        {
            base.OnAdLoaded(p0);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }


        public static void LaodInterstitial(Android.Content.Context context, string Adunit, Android.Gms.Ads.AdRequest adRequest, Android.Gms.Ads.AdLoadCallback Callback)
        {
            IntPtr AdRequestClass = JNIEnv.GetObjectClass(adRequest.Handle);
            IntPtr zzdsmethodID = JNIEnv.GetMethodID(AdRequestClass, "zza", "()Lcom/google/android/gms/internal/ads/zzbdq;");
            Java.Lang.Object zzzk = GetObject<Java.Lang.Object>(JNIEnv.CallObjectMethod(adRequest.Handle, zzdsmethodID), JniHandleOwnership.TransferLocalRef);

            IntPtr zzakjtype = JNIEnv.FindClass("com/google/android/gms/internal/ads/zzbof");
            IntPtr zzakjConstructor = JNIEnv.GetMethodID(zzakjtype, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V");
            IntPtr zzakjInstance = JNIEnv.NewObject(zzakjtype, zzakjConstructor, new JValue[] { new JValue(context), new JValue(new Java.Lang.String(Adunit)) });

            IntPtr LoadMethodId = JNIEnv.GetMethodID(zzakjtype, "zza", "(Lcom/google/android/gms/internal/ads/zzbdq;Lcom/google/android/gms/ads/AdLoadCallback;)V");
            JNIEnv.CallVoidMethod(zzakjInstance, LoadMethodId, new JValue[] { new JValue(zzzk), new JValue(Callback) });
        }
    }

u need to call it this way :

  AdRequest adRequest = new AdRequest.Builder().Build();
           InterstitialCallback.LaodInterstitial(this, "ca-app-pub-3940256099942544/1033173712", adRequest, new InterstitialCallback());

YoussefR33 avatar Jul 22 '21 23:07 YoussefR33

@r33software Thank you, you saved my life.

ntminhdn avatar Jul 28 '21 01:07 ntminhdn

RewardedAdLoadCallback fix , with the minimum code , without need to change project parameters about allowing unsafe code, the same logic can be applicable for any methods have the same issue .

 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);
        }
    }

create a class that inherit RewardedAdLoadCallback ,exemple : RewardedAdLoadCallbackinherit , and override the OnAdLoaded with RewardedAd type parameter, then call it this way , with the original Load method :

Android.Gms.Ads.Rewarded.RewardedAd.Load(this, "ca-app-pub-3940256099942544/5224354917", new AdRequest.Builder().Build(), new RewardedAdLoadCallbackinherit());

 public class RewardedAdLoadCallbackinherit : RewardedAdLoadCallback {

        public override void OnAdLoaded(Android.Gms.Ads.Rewarded.RewardedAd rewardedAd)
        {
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }

    }

YoussefR33 avatar Jul 29 '21 04:07 YoussefR33

@ntminhdn , check this new fix , it will works for all versions , and the logic can be applicable for other classes with same error like RewardedAdLoadCallback.

InterstitialCallback fix , with the minimum code , without need to change project parameters about allowing unsafe code.

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);
       }
   }

create a class that inherit InterstitialCallback,exemple : InterstitialCallbackinherit, and override the OnAdLoaded with InterstitialAd type parameter, then call it this way with the original Load method :

        `Android.Gms.Ads.Interstitial.InterstitialAd.Load(this, "ca-app-pub-3940256099942544/1033173712", new AdRequest.Builder().Build(), new InterstitialCallbackinherit());`
   public class InterstitialCallbackinherit : InterstitialCallback
    {
        public override void OnAdLoaded(InterstitialAd interstitialAd)
        {
            base.OnAdLoaded(interstitialAd);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }
    }

YoussefR33 avatar Jul 29 '21 04:07 YoussefR33

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);
   }

}

@r33software Thanks for your effort, above code could solve my issue successfully.

851265601 avatar Aug 13 '21 05:08 851265601

@r33software This is a very clean solution, thank you. I updated the gist at https://gist.github.com/dtaylorus/63fef408cec34999a1e566bd5fac27e5 with your changes.

dtaylorus avatar Aug 17 '21 15:08 dtaylorus

@r33software thank you!

Eversor avatar Sep 08 '21 09:09 Eversor

Cant believe after all this time this still hasnt been properly fixed.

luqman-hussain avatar Mar 04 '23 06:03 luqman-hussain

@ntminhdn , check this new fix , it will works for all versions , and the logic can be applicable for other classes with same error like RewardedAdLoadCallback.

InterstitialCallback fix , with the minimum code , without need to change project parameters about allowing unsafe code.

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);
       }
   }

create a class that inherit InterstitialCallback,exemple : InterstitialCallbackinherit, and override the OnAdLoaded with InterstitialAd type parameter, then call it this way with the original Load method :

        `Android.Gms.Ads.Interstitial.InterstitialAd.Load(this, "ca-app-pub-3940256099942544/1033173712", new AdRequest.Builder().Build(), new InterstitialCallbackinherit());`
   public class InterstitialCallbackinherit : InterstitialCallback
    {
        public override void OnAdLoaded(InterstitialAd interstitialAd)
        {
            base.OnAdLoaded(interstitialAd);
        }
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }
    }

Hi @YoussefR33 . It doesnt seem to work anymore? Even with 120.2.0 Only version that seems to work is 119.7.0 but on that currently always AdsFailedLoad is fire. Im guessing it needs to be on a newer version now and that one is probably out of use. Any suggestions?

luqman-hussain avatar Mar 04 '23 07:03 luqman-hussain