How to create an Android Module for a Titanium Mobile App– Part 1

In order to extend the functionality of the platform, required interactions with native modules are referred directly to the Android platform (Java).

andriod module b

Getting Started

The first step is to create a project from Titanium:

1.- File -> New -> Mobile Module Project

2.- In the next window, enter the data of project settings:

°Project name: Project name should NOT contain uppercase.
°Titanium SDK Version: the version we want to use for the project
°Deployment Targets: In this case we select Android

NOTE: It is important that the name of our WorkSpace does not contain spaces, otherwise we will have problems when creating the compiled.

3.- Press next and we’ll have the Module Manifest File:

°Version: The version of the module for example "1.0"
°Author, License and description: Extra information for the module.

4.- Last, press finish.

Working on the mobile app project

The structure of paper is as follows and it's important to detect some files that require special configuration.

Working with titanium

Folder src: where reside the core of our project folders all Java classes. By default Titanium generates 2 classes one XXXXModule.java and the other YYYProxy.Java. Here, we will discuss XXXXModule.java class.

Folder platform: Here in the folder platform / android (It’s no default, you must create it), there is our res folder where resides our layout, strings and other files necessary for our android project.

Build.properties: in this archive are configured the titanium’s routes, android and the google api, the api which is going to execute the compiled.

<span style="font-size: 1em;">titanium.platform=/Users/</span><span style="text-decoration: underline;">XXXXX</span><span style="font-size: 1em;">/Library/ApplicationSupport/</span><span style="text-decoration: underline;">Titanium</span><span style="font-size: 1em;">/</span><span style="text-decoration: underline;">mobilesdk</span><span style="font-size: 1em;">/</span><span style="text-decoration: underline;">osx</span><span style="font-size: 1em;">/3.1.0.GA/android</span>
<span style="font-size: 1em;">android.platform=/Users/</span><span style="text-decoration: underline;">XXXXX</span><span style="font-size: 1em;">/Downloads/android-</span><span style="text-decoration: underline;">sdk</span><span style="font-size: 1em;">-</span><span style="text-decoration: underline;">macosx</span><span style="font-size: 1em;">/platforms/android-8</span>
<span style="font-size: 1em;">google.apis=/Users/</span><span style="text-decoration: underline;">XXXXX</span><span style="font-size: 1em;">/Downloads/android-</span><span style="text-decoration: underline;">sdk</span><span style="font-size: 1em;">-</span><span style="text-decoration: underline;">macosx</span><span style="font-size: 1em;">/add-ons/</span><span style="text-decoration: underline;">addon</span><span style="font-size: 1em;">-google_apis-google-8</span>
<span style="font-size: 1em;">android.ndk=/Users/</span><span style="text-decoration: underline;">XXXXX</span><span style="font-size: 1em;">/Downloads/android-</span><span style="text-decoration: underline;">ndk</span><span style="font-size: 1em;">-r8e</span>

 

By default the Android ndk is not included; you can download it here.

You must check android.ndk parameter in this file to make the compiled. Once you have this file configured, next is to start working with our class Module which is the one that exposes methods to JavaScript, the structure by default that generates is:

/**
 *This file was auto-generated by the Titanium Module SDK helper for Android
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 */
packagecom.itexico.test;
 
importorg.appcelerator.kroll.KrollModule;
importorg.appcelerator.kroll.annotations.Kroll;
 
importorg.appcelerator.titanium.TiApplication;
importorg.appcelerator.kroll.common.Log;
@Kroll.module(name="Test", id="com.itexico.test")
public class TestModule extends KrollModule
{
 
                // Standard Debugging variables
                private static final String TAG = "TestModule";
 
                // You can define constants with @Kroll.constant, for example:
                // @Kroll.constant public static final String EXTERNAL_NAME = value;
 
                publicTestModule()
                {
                               super();
                }
 
                @Kroll.onAppCreate
                public static void onAppCreate(TiApplication app)
                {
                               Log.d(TAG, "inside onAppCreate");
                               // put module init code that needs to run when the application is created
                }
                // Methods
                @Kroll.method
                public String example()
                {
                               Log.d(TAG, "example called");
                               return "hello world";
                }
                // Properties
                @Kroll.getProperty
                public String getExampleProp()
                {
                               Log.d(TAG, "get example property");
                               return "hello world";
                }
 
                @Kroll.setProperty
                public void setExampleProp(String value) {
                               Log.d(TAG, "set example property: " + value);
                }
}
 
 

Compiling with AntTo expose a method to JavaScript is required to use the metatag @Kroll.method

Right click on buid.xml -> Run as -> Ant build

running an ant buildTo compile the project with Ant is simple. However, the first time we’ll have a problem.

The Android NDK problem:

Neither the ANDROID_NDK environment variable, or the android.ndk property is not set to an existing Android NDK installation (check your module's build.properties).

This error is the above NDK path in build.properties.

(android.ndk=/Users/XXXXX/Downloads/android-ndk-r8e)

Problem configuration for titanium SDK

exec returned: 2

This error is fixed by adding a property within the next file in the SDK (we use the location of the SDK you're using to compile the project) that we are using, in this case modify the 3.0.0 GA

Path to modify: ~/Library/ApplicationSupport/Titanium/mobilesdk/osx/3.0.0.GA/module/android

path to modify on titanium

Within the node <macrodef: Name="build.ndk"> Add the following line:

<arg value="NDK_PATH=${ndk.path}">

And it will remain this way:

&lt;macrodef name="build.ndk"&gt;
                     &lt;attribute name="gendir"/&gt;
                     &lt;sequential&gt;
                                     &lt;condition property="ndk.build"
                                                     value="${ndk.path}/ndk-build.cmd"
                                                     else="${ndk.path}/ndk-build"&gt;
                                                     &lt;os family="windows"/&gt;
                                     &lt;/condition&gt;
                                     &lt;property name="mobilesdk.dir" location="${titanium.platform}/.."/&gt;
                                     &lt;property name="ndk.verbose" value="0"/&gt;
                                     &lt;propertyregex property="user.name.nospaces" input="${user.name}" regexp=" " replace="_" global="true" defaultValue="${user.name}"/&gt;
                                     &lt;property name="tmpdir" value="${java.io.tmpdir}/${user.name.nospaces}/${ant.project.name}-generated" /&gt;
                                     &lt;mkdirdir="${tmpdir}" /&gt;
                                     &lt;copytodir="${tmpdir}" preservelastmodified="true" overwrite="true" includeEmptyDirs="true"&gt;
                                                     &lt;filesetdir="@{gendir}"/&gt;
                                     &lt;/copy&gt;
                                     &lt;exec executable="${ndk.build}" dir="${tmpdir}" failonerror="true"&gt;
                                                     &lt;arg value="TI_MOBILE_SDK=${mobilesdk.dir}"/&gt;
                                                     &lt;arg value="NDK_PROJECT_PATH=${tmpdir}"/&gt;
                                                     &lt;arg value="NDK_APPLICATION_MK=${tmpdir}/Application.mk"/&gt;
                                                     &lt;arg value="PYTHON=${python.exec}"/&gt;
                                                     &lt;arg value="V=${ndk.verbose}"/&gt;
                                                    <b> </b><span style="text-decoration: underline;"><b>&lt;arg value="NDK_PATH=${ndk.path}"&gt;</b></span>
 
                                     &lt;/exec&gt;
                                     &lt;movetodir="@{gendir}" preservelastmodified="true" overwrite="true" includeEmptyDirs="true"&gt;
                                                      &lt;filesetdir="${tmpdir}"/&gt;
                                      &lt;/move&gt;
                     &lt;/sequential&gt;
      &lt;/macrodef&gt;

NOTE: What is underlined is the only thing added

Android.mdk Error:

Once generated, the build open this file (Android.mk) in the main folder of your project and modify the following statement:

Android mk

"-I$(SYSROOT)/usr/include" It will be modified to look like this:

-I $ (NDK_PATH) / platforms / $ (TARGET_PLATFORM) / arch-arm/usr/include

The complete line remains like this:

LOCAL_CFLAGS := -g "-I$(TI_MOBILE_SDK)/android/native/include"  -I$(NDK_PATH)/platforms/$(TARGET_PLATFORM)/arch-arm/usr/include

Once this is done, now it's possible to generate the build with ant. You will get this message at the end of the build:

BUILD SUCCESSFUL

Total time: XX seconds

Zip Generation module for integration into Titanium Project

Once the build was generated within our folder dist, a zip file was generated which contains the module we just created. This build can be decompressed in two places.

1.- Unzip into the root of your project (As Local module)

2.- Unpack as a module for all our projects

About the Author

Tomas Garcia is a Computer Science Engineer with more than 6 years of experience as a software developer, web development, and almost 3 years in mobile app development. He currently works at iTexico as Web application and Mobile App Developer.

Oscar Salas

Written by Oscar Salas

Oscar Salas is a B2B Digital Marketing Specialist with 5 years of experience, who has helped organizations to grow and expand through strategic brand development and marketing programs. Analytical thinker, cat lover, he enjoys to play the piano and listening to Led Zeppelin He's currently leading the iTexico Demand Gen strategies.

Explore iTexico, The Nearshore + Company 

Learn More

Read More

Mobile Competency Center

Recent Posts