Black background behind billing dialogs

Hi guys,

When I trigger the google billing “buy dialog”, the dialog overlaps the game (aka you see your game in the background).

When you now minimize the game, and then activate it again, your game comes back up, but this time you can only see the buy dialog, the rest of the screen is black.

Does everyone have this, and/or does anyone know how to fix this?

Kind regards,
Mich

To answer my own question: This is due to stop/pausing the director when entering the background.
Disabling that fixes this issue.

What code did you end up using?

Hi Corytrese,

I ended up not stopping the animation on Android, like this:

void AppDelegate::applicationDidEnterBackground()
{
    theLog.WriteLine("AppDelegat=>applicationDidEnterBackground");

    // Pause the game
    if (m_pGameLayer)    { m_pGameLayer->Pause( true ); }

#ifndef __ANDROID__    // Stopping the animation on Android will result in graphics glitches when, for example, the billing dialog is on screen.
    cocos2d::Director::getInstance()->stopAnimation();    // Using this results in a black screen when the shop is on the screen and you rotate
//    cocos2d::Director::getInstance()->pause();            // This is replaced with stopAnimation
    // Save settings
    if (m_pGameLayer)    { m_pGameLayer->SaveSettings(); }    // Android saves settings OnStop, not OnPause.
#endif //!__ANDROID__

    // if you use SimpleAudioEngine, it must be pause    
    CocosDenshion::SimpleAudioEngine::getInstance()->pauseAllEffects();
    CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}


// The app is active again (regained focus)
void AppDelegate::applicationWillEnterForeground()
{
    theLog.WriteLine("AppDelegat=>applicationWillEnterForeground");

    // Unpause the game
    if (m_pGameLayer)    { m_pGameLayer->Pause( false ); }

#ifndef __ANDROID__
    cocos2d::Director::getInstance()->startAnimation();    // See stopAnimation comment in applicationDidEnterBackground()
//    cocos2d::Director::getInstance()->resume();            // This is replaced with startAnimation
#endif //!__ANDROID__

    // if you use SimpleAudioEngine, it must resume here
    CocosDenshion::SimpleAudioEngine::getInstance()->resumeAllEffects();
    CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}

Kind regards,
Michaël

For completeness sake, I should also explain what I did with settings saving.
I want the settings to save when the game gets minimized, not when it enters the background due to something showing on top of it.

To do this, you have to override the onStop function of your main activity.
Here is mine:

@Override
protected void onStop()
{
    // Save settings in the game here, as onStop is called when the application is actually minimized
    FileIO.nativeSaveSettings();
    super.onStop();
    if (m_analytics != null)    { m_analytics.onStop(); }
} 

The analytics line in there is to forward the stop to my google analytics layer (so I can call reportActivityStop).

The interesting part is the nativeSaveSettings call.
I have a FileIO class in C++ and Java. The jave code for this specific function is simple, as it just calls the C++ function. Like this:

public class FileIO
{
    public static native void nativeSaveSettings();
}

There is of course more code in my FileIO class, I just cut out the part you need for this.

The C++ side looks like this:

////////////////////////////////////////////////////////////////////////
// Save Settings (only used by Android)
////////////////////////////////////////////////////////////////////////
#if defined(__COCOS2DX__) && defined(__ANDROID__)
extern "C"
{
    void Java_com_gameplayheaven_library_FileIO_nativeSaveSettings( JNIEnv* env, jobject thiz )
    {
        AppDelegate*    pAppDelegate    = (AppDelegate*)cocos2d::Application::getInstance();
        GameLayer*        pGameLayer        = pAppDelegate ? pAppDelegate->GetGameLayer() : NULL;
        if (pGameLayer)    { pGameLayer->SaveSettings(); }
    }
}
#endif // __COCOS2DX__ && __ANDROID__

Basically, I catch the call and forward it to my game layer. Which in turn will pass it on to the game specific parts that need to save something (like settings, statistics, scores, etc).

In summary:
All you need to do to prevent the glitch, is NOT call stopAnimation (or any of it’s equivalents), just make sure you pause sound and music.

The other example code is to show where you can catch the real minimize of an app, and you could move the stopAnimation to there. I didn’t, as the game doesn’t receive any updates anymore once it’s minimized anyways…

Hope this helps!