defold / extension-admob

Defold native extension which provides access to AdMob functionality on Android and iOS
https://www.defold.com/extension-admob/
MIT License
37 stars 12 forks source link

Added support for app open ads #44

Closed britzl closed 8 hours ago

britzl commented 2 weeks ago

Fixes #23

britzl commented 2 weeks ago

The problem with the current solution is that it doesn't hook in before the DefoldActivity is shown the first time. Once the app is running and put in the background and then back to the foreground it works though.

In order to also show an add on app start we also need to extend the Application class (https://developers.google.com/admob/android/app-open#extend)

Note: A small Defold game that loads quickly would really not benefit from delaying gameplay while waiting for an ad to load and then show it. You can of course load the ad and then show it anyway even if the DefoldActivity has started and the engine has rendered for a second or two.

Thought: What if we don't do all of this stuff automatically in the extension and instead do it from Lua in window.set_listener() when we get a window.WINDOW_EVENT_FOCUS_GAINED event? And have an admob.load_appopen() and admob.show_appopen()?

AGulev commented 2 weeks ago

In order to also show an add on app start we also need to extend the Application class (https://developers.google.com/admob/android/app-open#extend)

I think it's possible to avoid:

static bool g_IsAppInitialized = false;

static void OnCreateApp(JNIEnv* env, jobject activity)
{
  // just to make sure it's ccalled only once
  // there is an issue with UnregisterOnActivityCreateListener
  if (!g_IsAppInitialized)
  {
    // Don't usee dmAndroid::LoadClass on OnCreate on some android versions g_AndroidApp->activity->clazz
    // isn't initialized yet!
    jclass na_class = env->FindClass("android/app/NativeActivity");
    jmethodID get_class_loader = env->GetMethodID(na_class,"getClassLoader", "()Ljava/lang/ClassLoader;");
    jobject cls = env->CallObjectMethod(activity, get_class_loader);
    jclass class_loader = env->FindClass("java/lang/ClassLoader");
    jmethodID find_class = env->GetMethodID(class_loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
    jstring str_class_name = env->NewStringUTF("com/defold/admob/AdmobJNI");
    jclass admob_cls = (jclass)env->CallObjectMethod(cls, find_class, str_class_name);
    env->DeleteLocalRef(str_class_name);
    jmethodID method = env->GetStaticMethodID(admob_cls, "AdMob_OnCreate", "(Landroid/app/Activity;)V");
    env->CallStaticVoidMethod(admob_cls, method, activity);
    g_IsAppInitialized = true;
  }
}

struct AdMobStaticInit
{
  AdMobStaticInit()
  {
    dmAndroid::RegisterOnActivityCreateListener(OnCreateApp);
  }
} g_AdMobStaticInit;
public static void AdMob_OnCreate(final Activity appActivity) {
// your OnCreate logic here
}

It should work

britzl commented 11 hours ago

Should it be shown on iOS right after I run app? Because now it's shown only when I lock unclock phone

Let me have a look!

britzl commented 10 hours ago

Should it be shown on iOS right after I run app? Because now it's shown only when I lock unclock phone

Let me have a look!

Ok, it works now.

AGulev commented 10 hours ago

Great!