xamarin / GooglePlayServicesComponents

Other
316 stars 147 forks source link

Name Clash in InterstitialAdLoadCallback and RewardedAdLoadCallback #425

Open BilKaz opened 3 years ago

BilKaz commented 3 years ago

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
Mataboge commented 3 years ago

I can confirm the issue.

simonsymhoven commented 3 years ago

I can confirm the issue.

Yes, same here!

TomasHadraba commented 3 years ago

Same here!

moljac commented 3 years ago

Thanks for the feedback.

Can you provide minimal repro sample, please?

TomasHadraba commented 3 years ago

OnAdLoadedSample.zip

YoussefR33 commented 3 years ago

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 .

Mataboge commented 3 years ago

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

kenchan97 commented 3 years ago

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 :)

YoussefR33 commented 3 years ago

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).

assassin316 commented 3 years ago

@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?

jvreeker commented 3 years ago

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

dtaylorus commented 3 years ago

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.

BilKaz commented 3 years ago

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

hsto-code commented 3 years ago

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.

thakanoduncu commented 3 years ago

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.

assassin316 commented 3 years ago

@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.

dtaylorus commented 3 years ago

@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.

glintpursuit commented 3 years ago

@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);
        }
    }
dtaylorus commented 3 years ago

@glintpursuit Override OnRewardedAdLoaded, not OnAdLoaded.

glintpursuit commented 3 years ago

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);           
        }
    }
ntminhdn commented 3 years ago

@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)
YoussefR33 commented 3 years ago

@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());
ntminhdn commented 3 years ago

@r33software Thank you, you saved my life.

YoussefR33 commented 3 years ago

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 commented 3 years ago

@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);
        }
    }
851265601 commented 3 years ago

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.

dtaylorus commented 3 years ago

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

Eversor commented 3 years ago

@r33software thank you!

luqman-hussain commented 1 year ago

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

luqman-hussain commented 1 year ago

@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?

mhdwaelanjo commented 1 year ago

I fixed the problem.. we can use my libraries :

 <PackageReference Include="Anjo.Android.GoogleServices.Ads" Version="22.0.0" />
 <PackageReference Include="Anjo.Android.GoogleServices.AdsBase" Version="22.0.0" />
 <PackageReference Include="Anjo.Android.GoogleServices.AdsLite" Version="22.0.0" />

Supports fixing the problem of Loading ads using :