Handling Android Native Activities like a Pro


amber_devices_2Due to popular request, we have enhanced the JavaFX Mobile SDK for Android with the ability to communicate between your JavaFX Application and other applications running on the device.

Android developers are familiar with the concepts of Intents and Activities, and with the ability to transfer control from your application to another application in order to achieve a result from this application.

In order to enable this functionality in JavaFX, we added a function on javafxports.android.Activity: Activity.setOnActivityResultHander (IntentHandler handler);

An example of this functionality is available in the Gluon samples repository, and this functionality is available in the Gluon JavaFX Mobile SDK for Android that we released earlier this week.

In the sections below we will briefly describe how this works, and how you can extend your JavaFX codebase with some native implementation, in case Charm Down doesn’t provide it yet.

Getting started

Create a project using the Gluon Plugin on your favorite IDE. Notice you will have an Android package, where you can place Android native code.

Defining the service

Let’s define an interface with the methods we want to execute in the running platform. For the sake of simplicity, we’ll focus on a photo gallery sample: we want to take a picture with the device’s camera or we want to retrieve an image from the device’s gallery. Either way, we’ll have a javafx.scene.image.Image as a result, bundled in an observable property.

We are working on an implementation on iOS. Once this is ready, this functionality can be added to Charm Down, and developers don’t have to write boilerplate code for platform-specific functionality. For now, the platform-detection is done in the sample below.

In order to call that Android native code from the JavaFX code in the main package, we create an abstract class with an abstract method returning the native interface. We will subclass it in the specific platforms, providing native implementations of the service, as well.

Once we know the platform we are running on, we can load at runtime the specific subclass:

Finally, in our JavaFX application class we can create a platform-agnostic instance of the service, that will run only on the specific platform:

In case we are running on Android, this will be the subclass called when getPlatform() is invoked:

The service

Time to define the service on Android:

And finally, time to get dirty going down into native Android code, fulfilling the required services.

Let’s focus on taking a picture with the camera.

Launching the activity

Usually, we create an Intent, and launch it from our JavaFX activity:

This activity will launch the camera on the device, outside the JavaFX thread and outside our application.

Waiting for the activity to finish

With the new implementation provided in the JavaFX Mobile SDK for Android, we are able to wait until the launched activity finishes, process the result, and go back to our app and JavaFX thread. So we have to add the result handler before launching the activity:

Getting the image

Now, in our main application, we can simply listen to changes in fxImage, and load the new image inside an ImageView.

As a result, we can take a picture with our android device’s camera, and load it in our application. This is shown in the screenshots below:

Summary

We have seen in detail how to add Android native code in our application, in order to make use of one of the many native services we can find on our devices.

Check all the code in the repository to find out about the rest of the services included in GoNative. And check also Charm Down for an platform-agnostic API already available for several services like local storage or GPS.

We look forward to what you can achieve with this new functionality, and we hope to see your contributions to Charm Down to support new functionality!