Java-K
Java-K

Reputation: 497

CodenameOne Navigating from Splash Screen to "first time use" form in UIBuilder app

I have a tricky situation that only appears in mobile devices, not the simulator, so I need some expert help to troubleshoot. It's like the stateMachine takes me back to the SplashScreen briefly (or does some strange back-transition) after displaying my "FirstTimeSetup" form.

Here's my setup: I used the GUIBuilder to build the app with a form SplashScreen that will show first and then auto-transition to a form Main after some network connections happen in processBackground.

That works fine but on the First time starting, (when a Preference is not set) I want to display a different form: FirstTimeSetup. The best way I could see to do this was the following:

1) in processBackground, immediately return false if it's the first time running so that it doesn't transition to Main.

protected boolean processBackground(Form f) {
    if ("SplashScreen".equals(f.getName())) {
        if (Preferences.get(PREFS_FIRST_TIME_SETUP,true)){
            //return false to indicate that we should not proceed to next_form specified in property
            //we do this because postSplashScreen will trigger the load of the "FirstTimeSetup" form
            return false;
        }
        //...continue with normal app initialization if this is not the first time

2) In postSplashScreen, I again check if it's a first-time load and then disable back-commands and call showForm to the First Time Setup form.

@Override
protected void postSplashScreen(Form f) {
    if (Preferences.get(PREFS_FIRST_TIME_SETUP, true)) {
        //disable back command for this form
        setBackCommandEnabled(false);
        showForm("FirstTimeSetup", null);
    }
}

3) in postFirstTimeSetup method, I display some dialogs to explain the next steps to the user, do some network checks to ensure we can proceed with registration, and then end the method so the user can interact with the dialog and register. It's at this point when on the iOS or Android Device, I see a slide transition to the SplashScreen and then immediately it re-displays the FirstTimeSetup form, and it does this twice before the user is able to interact with the form.

4) Sometimes (it's inconsistent), the postFirstTimeSetup method will execute again (the same dialog boxes prompting the user are displayed again!).

It feels like some SplashScreen automatic transition is still trying to execute after I've returned false from processBackground and the postSplashScreen method is already complete... any suggestions would be helpful to eliminate this strange double-transition!

UPDATE: With further tweaking and Investigating I realized that this appears to be caused by Android Permissions dialogs which is why it only happens on initially installing the app.

In processBackground, I make the first network calls (prompting network usage permission dialog) and access the device parameters IMEI And UUID to get a device identifier (prompting the "allow access to Phone" permission). After dismissing each dialog, the SplashScreen form appears to be re-entered causing a re-display of the form with transition animation (and I think also re-running the processBackground! re-doing all my splash screen initialization work!).

So here's the updated question: How can I get the Android Permissions dialogs to stop the SpashScreen from reloading?

I've tried moving the commands that trigger out to initVars, but then I get the permissions dialogs on a Blank screen, and then the splash screen just transitions twice rapidly like I shared in this video: youtu.be/2QpdaeigNZ8

I've tried wrapping the two "triggers" (commands that cause the permissions) in a callSerially() so that it would delay the dialogs until the SplashScreen form is at least displayed, but then the form displays, and a permission dialog shows, I click "allow" and then the splashScreen Form display again, then the second permission dialog pops up. I clock allow and then AGAIN a re-display of splashScreen.

Upvotes: 3

Views: 298

Answers (1)

Diamond
Diamond

Reputation: 7483

The solution is to perform your logic in processBackground() and get rid of postSplashScreen, then return false at the end of this method.

@Override
protected boolean processBackground(final Form f) {
    if ("SplashScreen".equalsIgnoreCase(f.getName())) {
        new UITimer(() -> {
            if (Preferences.get(PREFS_FIRST_TIME_SETUP, true)) {
                showForm("FirstTimeSetup", null);
            } else {
                showForm("Main", null);// or any other form you want to show
            }
        }).schedule(3000, false, f); //wait 3 seconds before proceeding
    }
    return false; //always return false at the end
}

Then in your FirstTimeSetup form's postShow() (i.e. postFirstTimeSetup() method), remember to set PREFS_FIRST_TIME_SETUP to false.

Preferences.set(PREFS_FIRST_TIME_SETUP, false);

Upvotes: 2

Related Questions