At Shockoe, we are given the opportunity to work on innovative projects that push to incorporate the latest technologies. Upon entering Shockoe, my first assignment was to develop a native module to allow bluetooth barcode scanners to pair and interact with an android device via the app. As this was my first time jumping into both titanium and java, I was thoroughly confused on how to accomplish my assignment.

 

Through scavenging together documentation and filtering through previous projects, I somehow got the job done. For those of you who may be new to titanium and modules, here are some useful tips and broken down concepts that I used to make module development easier.

 

Creating a shell script for building and packaging your module

*Primarily for CLI users

 

If you’ve done module development before, you know it can be a chore to integrate your module into your titanium project. You have to build the module, delete it from your titanium project if it is already installed, uncompress the module into your project and install it locally.

 

Having to do this process over and over while testing a module can take up an unbelievable chuck of your development time. Luckily for me, my co-worker Eric, a developer who I was collaborating with to create the module, came up with the idea to use a shell script to build our module and integrate it into the titanium project for us.

 

Here is an example of the script:

bluetoothmodule.sh

#!/bin/sh
 

#Remove the current module from the project folder
rm -r ~/Files/Projects/BlueToothFolder/BluetoothDemo/modules/android/com.shockoe.bluetoothModuleDemo

#Navigate to the module project folder
cd ~/Files/Projects/BlueToothFolder/modules/bluetoothModuleDemo/android

#Clean the folder
ant clean

#Run ant to build the project
ant
 

#Unzip the created folder
cd dist/
unzip -o com.shockoe.bluetoothModuleDemo-1.0.0.zip

#Move the unzipped folder into the Titanium folder
cd modules/android

mv com.shockoe.bluetoothModuleDemo/ ~/Files/Projects/BlueToothFolder/BluetoothDemo/modules/android

#Alert when finish and return back to the project folder

echo "Finished"

cd ~/Files/Projects/BlueToothFolder/BluetoothDemo/ 

#Build the project to your connected device

appc run -p android -T device

This script saved me countless hours of having to re-build and install my tests while developing the module. Feel free to use it and edit it to your needs!

 

Exposing Methods

To allow your titanium project to access methods in your module, you can expose methods through the @Kroll.method annotation.

A simple example:

bluetoothModuleDemoModule.java

@Kroll.method
public String returnstring(String testString){
	return testString;
}

Then in your index.js:

index.js

// Require the module into your controller
// This particular module is Android only
if(OS_ANDROID){
	var blueToothDemo = require('com.shockoe.bluetoothModuleDemo');
}
console.log(blueToothDemo.returnstring(‘Hello World!’));

And as expected, ‘Hello World’ is printed to our console.

 

Here is a simple example that I used in the bluetooth module:

bluetoothModuleDemoModule.java

// Expose the method
@Kroll.method
public void enableBluetooth(){
	// Determine if bluetooth is enabled or not on the device
	if(!bluetoothAdapter.isEnabled()){
		// If bluetooth is not enabled, enable it now
		bluetoothAdapter.enable();
		Log.d(TAG, "Bluetooth Enabled”);
	}		
}

Now in our controller we will be able to directly call the enableBluetooth function:

index.js

// Call the enableBlutooth function in the module
blueToothDemo.enableBluetooth();

 

Firing Events

Just like how you can trigger events in Javascript, you can trigger events in the module’s Proxy through its built-in event management with fireEvent and hasListeners.

A simple example:

bluetoothModuleDemoModule.java

// Some method that gets called to fire a string after it is given data
private void exampeFire(String data){
	if(data == null)
	return;
		
	this.fireEvent("sendData", data);
}

In your controller, you would receive the data listen for the data like this:

index.js

// Listen for emitter from the bluetooth module
blueToothDemo.addEventListener(‘sendData’, obtainedData);

function obtainedData(data){
	console.log(‘received the following data: ‘ + data);
}

In a larger concept, this is how I used fireEvent within the bluetooth module:

bluetoothModuleDemoModule.java

// Using the BroadcastReceiver for registering when a bluetooth device is found.
    private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Message msg = Message.obtain();
            String action = intent.getAction();
            
            if(BluetoothDevice.ACTION_FOUND.equals(action)){

            	bluetoothDevice        = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            	BluetoothClass blclass = intent.getParcelableExtra(BluetoothDevice.EXTRA_CLASS);
            	
            	int Majorclass = blclass.getMajorDeviceClass();
            	int minorclass = blclass.getDeviceClass();
            	
            	
                deviceList = new KrollDict();
                
                try{
                	deviceList.put("name",bluetoothDevice.getName());
                	deviceList.put("macAddress",bluetoothDevice.getAddress());
                	deviceList.put("pairedStatus",bluetoothDevice.getBondState());
                }
                catch (Exception e) {
                    Log.w(TAG, "devicesFound exception: "+e.getMessage());
                    postError(e.getMessage());
                }

                devicesFound();
                
            } 
        
        }
    };	

// Fire the event with our deviceList to our titanium project
private void devicesFound(){    	
    	this.fireEvent("devicesFound", deviceList);     			
}

And just like in the simple example, we will listen for the event in our controller:

index.js

// Listen for emitter from the bluetooth module
blueToothDemo.addEventListener(‘devicesFound’, devicesFound);

var devicesFound = function(e){
	console.log(e.name);
}

Our deviceList from the module’s devicesFound method will be represented by e. If all went well, then console.log(e.name) should print the bluetooth device’s name into our logs!

Exposing methods and firing events was the bulk of the information that I needed to comprehend to get started on my bluetooth module. Hopefully this helps a titanium and module novice get their start on their project as well.

 

Small Tips

  • If you’re new to modules, I would play around with Appcelerator’s ti.moddevguide on github. To reach the module code, follow the path in the src folder. To see how the module can be implemented into a titanium project, check out example/navigator.js.
  • Find or develop a native method of what you would like your module to do and break it down to be usable in a module. Determine what methods to expose and where events need to be fired
  • Read Appcelerator’s Module Architecture Guide. The docs do an excellent job at detailing the various ways to expose methods and handle properties.
  • Specifically for bluetooth, read Android’s developers guide for bluetooth development