4

I am using C2DM together with PhoneGap. When I receive a C2DM message, I display a notification (via NotificationManager). When the user selects the notification then my application receives an intent. In that case I want to activate a page within my jquery-mobile webapp.

Therefore I overrode the onNewIntent event to store the intent:

@Override
protected void onNewIntent(final Intent intent)
{
    super.onNewIntent(intent);
    setIntent(intent);
}

Then, in onResume I activated the correct page if the intent was from C2DM:

@Override
protected void onResume()
{
    super.onResume();

    // read possible argument
    boolean showMessage = getIntent().getBooleanExtra(ARG_SHOW_MESSAGES, false);
    if (showMessage)
    {
        clearNotification();
        super.loadUrl("file:///android_asset/www/de/index.html#messages");
    }
}

This works fine but it crashes sometimes with a NullPointerException - not on my mobile or emulator, but on other devices. The stacktrace says it is in the onNewIntent of the DroidGap activity, see Code:

protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    //Forward to plugins
    this.pluginManager.onNewIntent(intent);
}

I wasn't able to reproduce this situation. Obviously pluginManager is null but I don't why.

So the questions are:

  • Is the taken approach to select a specific page in jquery-mobile from Android good or can someone point out a better approach?
  • How can I get rid of the exception? Of course I could check pluginManager for beeing null and in this case don't call super - but then my specific page isn't activated.
  • Do you think this is a PhoneGap bug - not to check pluginmanager for null? When I checked the PhoneGap code I thought this should never happen, in my understanding onNewIntent is only called when the activity is loaded, otherwise onCreate would be triggered instead.

Update I know more now: problem occurs when the app is not loaded and a C2DM message arrives. The intent starts the app, the events occur in the following order - but onNewIntent is only called occasionally:

onCreate()
onNewIntent()
onResume()

Whenever onNewIntent is executed during the startup it crashes. Anyway I fixed this with:

@Override
protected void onNewIntent(final Intent intent)
{
    // avoid Phonegap bug
    if (pluginManager != null)
    {
        super.onNewIntent(intent);
    }
    setIntent(intent);
}

When I want to change the start page in the onResume-Event, this doesn't work when Phonegap is not ready. So it is just to early to call the #messages page in onResume in the case that the application is starting. But when to call it then? Is there a possiblility to hook into onDeviceReady?

ChrLipp
  • 15,526
  • 10
  • 75
  • 107

1 Answers1

1

I still do not know why sometimes onNewIntent is triggered during a application start (not just activated) and sometimes not. Anyway I solved all my problems with some workarounds.

In my activity I created a new function (not relevant parts are stripped):

public void onDeviceReady()
{
    if (!isReady)
    {
        super.loadUrl("file:///android_asset/www/en/index.html#messages");
    }

    // activate onResume instead
    isReady = true;
}

and the boolean flag above:

/** Is PhoneGap ready? */
private boolean isReady = false;

I activate the callback in the onCreate event:

// Callback setzen
appView.addJavascriptInterface(this, "Android");

and call it from the Javascript onDeviceReady

if (OSName == "Android")
{
    window.Android.onDeviceReady();
}

In the onResume event I use the negotiated logic:

protected void onResume()
{
    super.onResume();

    if (isReady)
    {
        super.loadUrl("file:///android_asset/www/en/index.html#messages");
    }
}

This guarantees that the page selection is executed only once, either in onResume or in onDeviceReady.

ChrLipp
  • 15,526
  • 10
  • 75
  • 107