libgdx / libgdx

Desktop/Android/HTML5/iOS Java game development framework
http://www.libgdx.com/
Apache License 2.0
23.28k stars 6.44k forks source link

RoboVM touchpoints stay down forever after displaying admob interstitial while touching screen #4190

Closed doomtoo closed 4 years ago

doomtoo commented 8 years ago

Issue details

If you are touching the screen and display an admob interstitial, when you close the interstitial, that touchpoint remains stuck down where it was (Gdx.app.getInput().isTouched(0) is now always down at the point you had been touching). If you touch on the screen again, it's now pointer 1, because 0 has been locked as always down.(and you can repeat it, locking all touchpoints)

Reproduction steps/code

Steps Overview: 1) Create a new LibGDX roboVM project 2) Get the project setup to display an Admob interstitial ad 3) Have an ad appear while touching the screen 4) (remove your finger) Close the ad, the input will still be counted as being held down- any new inputs will be the next pointer 5) repeat until all 10 fingers are counted as being down while not touching the screen

Steps More in depth: 1) Create a new LibGDX roboVM project 2) Add everything to be able to display admob ads from the updated robopods: a) In the build.gradle for the project, in the buildscript->dependiencies, change the mobidevelop class path to version '2.2.0-SNAPSHOT' b) In the allprojects->ect section, change the roboVMVersion to '2.2.0-SNAPSHOT', and add 'robopodsVersion' with the same version c) Add to the ios dependencies: compile "com.mobidevelop.robovm:robopods-google-mobile-ads-ios:$robopodsVersion" d) Download the Admob iOS library, and put the 'GoogleMobileAds.framework' into a new folder in the iOS project called 'libs' e) In robovm.xml in the iOS project add:

<frameworkPaths>
    <path>libs</path>
  </frameworkPaths>
   <frameworks>
    <framework>GoogleMobileAds</framework>
    <framework>UIKit</framework>
    <framework>OpenGLES</framework>
    <framework>QuartzCore</framework>
    <framework>CoreGraphics</framework>
    <framework>OpenAL</framework>
    <framework>AudioToolbox</framework>
    <framework>AVFoundation</framework>
    <framework>SafariServices</framework>
    <framework>CoreBluetooth</framework>
    <framework>AdSupport</framework>
    <framework>AudioToolbox</framework>
    <framework>AVFoundation</framework>
    <framework>CoreGraphics</framework>
    <framework>CoreData</framework>
    <framework>CoreMedia</framework>
    <framework>CoreTelephony</framework>
    <framework>EventKit</framework>
    <framework>EventKitUI</framework>
    <framework>MediaPlayer</framework>
    <framework>MessageUI</framework>
    <framework>QuartzCore</framework>
    <framework>StoreKit</framework>
    <framework>SystemConfiguration</framework>
  </frameworks>

3) Create a new Interface in your core project to call the interstitial from:


public interface AdTest
{
    public void Update(float deltaTime);
    public void RequestAd();
}

4) Call the AdTest.Update function from your Game render loop:

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class Game extends ApplicationAdapter
{
    SpriteBatch batch;
    Texture img;
    AdTest test;

    public Game()
    {

    }

    public Game(AdTest test)
    {
        this.test=test;
    }

    @Override
    public void create ()
    {
        batch = new SpriteBatch();
        img = new Texture("badlogic.jpg");
    }

    @Override
    public void render ()
    {
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw(img, 0, 0);
        batch.end();

        test.Update(Gdx.graphics.getDeltaTime());
    }

    @Override
    public void dispose ()
    {
        batch.dispose();
        img.dispose();
    }
}

5) Create your Ad interface in your iOS project

import com.badlogic.gdx.Gdx;
import org.robovm.apple.uikit.UIApplication;
import org.robovm.apple.uikit.UIViewController;
import org.robovm.pods.google.mobileads.GADInterstitial;
import org.robovm.pods.google.mobileads.GADRequest;
public class AdTestIOS implements AdTest
{
    GADInterstitial adInterstitial;

    float ad_display_timer =0;
    final float ad_display_delay =10;

    float log_timer=0;
    final float log_delay=1;

    public AdTestIOS()
    {
        RequestAd();
    }

    @Override
    public void RequestAd()
    {
        GADRequest request = new GADRequest();
        request.setTestDevices(java.util.Arrays.asList(GADRequest.getSimulatorID()));
        adInterstitial = new GADInterstitial("ca-app-pub-3940256099942544/4411468910");
        adInterstitial.loadRequest(request);
    }

    @Override
    public void Update(float deltaTime)
    {
        ad_display_timer +=deltaTime;
        if(ad_display_timer > ad_display_delay)
        {
            ad_display_timer =0;
            if (adInterstitial.isReady())
            {
                UIViewController viewController = UIApplication.getSharedApplication().getKeyWindow().getRootViewController();
                adInterstitial.present(viewController);
                RequestAd();
            }
        }
        UpdateUI(deltaTime);
    }

    public void UpdateUI(float deltaTime)
    {
        log_timer+=deltaTime;
        if(log_timer>log_delay)
        {
            log_timer=0;
            Gdx.app.log("AdTestIOS", "Press and hold the screen until ad appears in " + ((int) (ad_display_delay - ad_display_timer)) +
                    "s. isTouched(0)=" + Gdx.input.isTouched(0) + ": \"+. isTouched(1)= "+ Gdx.input.isTouched(1));
        }
    }
}

6) Pass your iOS interface to the Game when starting up the IOSLauncher:

import org.robovm.apple.foundation.NSAutoreleasePool;
import org.robovm.apple.uikit.UIApplication;

import com.badlogic.gdx.backends.iosrobovm.IOSApplication;
import com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration;

public class IOSLauncher extends IOSApplication.Delegate 
{
    @Override
    protected IOSApplication createApplication() 
    {
        IOSApplicationConfiguration config = new IOSApplicationConfiguration();
        return new IOSApplication(new Game(new AdTestIOS()), config);
    }

    public static void main(String[] argv) 
    {
        NSAutoreleasePool pool = new NSAutoreleasePool();
        UIApplication.main(argv, null, IOSLauncher.class);
        pool.close();
    }
}

7) Run the app on iOS. Press on the screen and wait for the Ad to appear. Let go when the ad appears, and close it. The console will show that it still thinks input[0] is locked down. Repeat, and input[1] will also be locked, and so on.

Version of LibGDX and/or relevant dependencies

gdxVersion = '1.9.3' roboVMVersion = '2.2.0-SNAPSHOT' robopodsVersion = '2.2.0-SNAPSHOT'

Stacktrace

//NA

Context

Someone is playing the game, they die, an ad pops in, they close it, and every finger that was used while playing is still down, and they can no longer control the game.

Please select the affected platforms

obigu commented 4 years ago

This one is a bit old and I'll close but feel free to reopen. I think the issue may be on how AdMob has been implemented, check SO thread for reference https://stackoverflow.com/questions/26528977/detect-close-of-interstitial-ad-in-admob-using-ios-robovm-libgdx.