onOpen and Android – the ugly

A guest-blog by Titanium expert and trainer Ray Belisle from Canada.


I admit – I always develop for iOS first, Android second. This is because of a very practical reality. Even when I am developing an app for both platforms, I test and refine on iOS first because I know that once I am done with the app submission to Apple, I have somewhere between 3 and 14 days before it will be approved. This gives me time to refine my Android code before submitting to the Play store. Since Google will only take hours to publish, this has been a pattern I have followed for some time.

Initialising views

Though I keep Android in mind in all my coding, and after many years working with Titanium, I know where most of the pitfalls are, I have had this one bite me a few times and thought I would share. When working with the Alloy MVC framework, the code in your Controller file will run sequentially from top to bottom. The issue I have seen regularly is code that REQUIRES your view to be instantiated PRIOR to running. This came to light again recently when working with NFC (Near Field Communication) on Android.

NFC example

You can take a look at the NFC Foreground demo from Appcelerator on GitHub.

This NFC demo is supposed to setup a NFC foreground receiver waiting for one device to send an NFC request to the other. When you run this, the first NFC send is intercepted by the default device handler instead of the Titanium app, but any subsequent do works. Why? Let’s examine.

In the code example above, the following code is run to get the current activity from android.

// Must wait until the activity has been opened before setting up NFC
$.index.addEventListener('open', function(e) {
  setupNfc();
});

Window activities

The INTENT (not Android Intent) of this code is to wait until the activity has been opened before running the setupNfc() code. The problem is that, even though the intent of this code is to wait until the window is opened, in reality, the first time this code is run, the activity is NOT available. That is why the first time it the app receives a code, the default handler of the device receives the send notification. So why doesn’t this work? I wish I knew, but I have seen it in different circumstances as well (I guess it really is time to log something in JIRA!)

But there is a workaround. If you remove the code from the js file and instead call the function from the onOpen event of the object defined in the XML view, all is good!

In this example, delete the addEventListener code and then open the index.xml and update the following line:

<Window class="container">

and change it to:

<Window class="container" onOpen="setupNfc">

Use onOpen instead of inline

So, the moral of the story is, if you have ANY initialisation code that needs to be run for your window, put the code in a function instead of being inline in the js file, then call the function from the onOpen event of your window! That will give you what you expect in Android (never a problem in iOS BTW, but something to do so that you know it will work with Android later!)

One more thing

If you decide to try the code from the example above to test my theory, there is another problem with the index.js code for this example. On line 62, there is the following code:

var act = Ti.Android.currentActivity;

You should replace that with:

var act = $.index.activity;

If you’re using a TabGroup make this getActivity() instead.

Ray Belisle is the owner of MobilExperience, an Appcelerator consultant based in Calgary Canada. In addition to using Titanium for over 4 years he is an Appcelerator Certified Developer, an Appcelerator Titan and the first certified Trainer in Canada.


Comments

  • Nicola

    Hi Ray, I’m trying to use the NFC module but after two days I’m still stuck. I’ve tried your solution and others before that, but the best I got was a vanishing screen displaying the tag.
    Could you please post or send a zip with the complete working app?
    Thanks!!!

  • John Staunton (@JohnCStaunton)

    I have the same issue as Nicola! Any help / suggestions would be much appreciated…

  • Adeldel Emam

    Hello,
    did any one reached to a solution for this as we are still stuck with the NFC issues, any help or working sample please,
    its unbelievable with this amount of many people have problem with it with no reply so appcelerator can easily announce that they don’t support NFC anymore better!