Create BlackBerry applications with open source tools, Part 1: Laying the groundwork

There is perhaps no bigger market-transformational technology than the cell phone. And within that classification of devices, perhaps none more recognizable than the BlackBerry from Research In Motion (RIM). Most people think it is just for business e-mail, but there is untapped potential in that addictive device. Despite being a popular platform, third-party applications are still needed for the BlackBerry platform. There is no better way to bring those applications to fruition than to enable the help from the open source community. Follow along as this tutorial lays the groundwork for an open source data-collection application, upon which an accessible and easy-to-use data-collection service is built.

Share:

Frank Ableson, Author

After his college basketball career came to an end without a multiyear contract to play for the L.A. Lakers, Frank Ableson shifted his focus to computer software design. He enjoys solving complex problems, particularly in the areas of communications and hardware interfacing. When not working, he can be found spending time with his wife Nikki and their children. You can reach Frank at frank@cfgsolutions.com.



19 August 2008

Also available in Portuguese Spanish

Before you start

This tutorial is for open source and Java™ technology developers interested in BlackBerry application development in the context of a mobile data-collection application. The example application demonstrates a simple data-collection application leveraging the freely available BlackBerry development tools. Mobile development experience is helpful, but not required. Java programming skills are required for BlackBerry applications, but are not an explicit requirement for this tutorial. Likewise, PHP and MySQL are employed on the back end, so familiarity with those platforms is helpful, but, again, not a requirement.

About this tutorial

So why are we concerned about writing applications for BlackBerry? One of the challenges of open source software is that it is often seen with only a single face — Linux®— and that is often hidden on a server buried in a data center. However, one of the biggest secrets in the market is that the most popular and powerful mobile platform uses an open source programming language: the Java programming language. That's right, an open source language powers the applications in the BlackBerry devices used every day.

BlackBerry applications represent an interesting convergence of usage profile and capability. The prototypical user of a BlackBerry is a professional who uses a BlackBerry for work. BlackBerry devices allow people to be more available and real-time because BlackBerry is the current leader in mobile e-mail use. But the BlackBerry platform offers more than just e-mail. Built upon a J2ME foundation, RIM has extended the Java environment to provide powerful and desirable features enabling useful and fun applications for business and entertainment alike. As new mobile platforms come on the scene, the measuring stick is BlackBerry. If other platforms compare themselves to BlackBerry, there is motivation enough to explore the capabilities of this market-moving platform.

This tutorial introduces BlackBerry application development within the context of the mobile data-collection application space. It provides an introduction to BlackBerry development with a quick introduction to the platform, a tour of the BlackBerry development tools, and construction of a complete data-collection application. Complete source code is available for the BlackBerry application and the server-side components used in the sample application in the Download section. This tutorial is organized into the following sections:

  • BlackBerry platform basics
  • BlackBerry application development with JDE
  • Data-collection applications with BlackBerry
  • Transaction processing on the server side
  • Next steps

System requirements

This tutorial demonstrates a few open source technologies and stitches them together to form a prototype for an open source mobile data-collection platform. You need all of them to perform the steps in this tutorial. Our primary focus is developing applications for the BlackBerry platform, so those pieces are the primary requirement. You can leverage a publicly available Web site for server-side transactions if building out the server side is not of interest to you. Here's the full list:

BlackBerry Java Development Environment
This tutorial employs V4.0.2 of the JDE, although a later version is available.
PHP
PHP may be downloaded from PHP.net. The latest stable release is V4.4.9.
MySQL
The latest stable release is V5.0.
IBM Tutorial on BlackBerry Data Collection Applications
Access the author's site hosting the server-side transactions.

Sample code highlights

In this tutorial, a generic data-collection application is constructed for the BlackBerry. It has the uninspiring name of bb_ibm_demo. But don't let the name fool you. When the concepts presented are absorbed, a whole host of useful applications await. Full source code is available in the Download section. Source-code snippets include:

bb_ibm_demo constructor
This is the primary class of the BlackBerry application.
main() method in bb_ibm_demo of the BlackBerry application
This is the public static void method for the application (the entry point of the BlackBerry application).
bb_ibm_screen constructor
This is the actual user interface (UI) shown to the user on the BlackBerry. This method demonstrates the creation of the UI elements.
fieldChanged()
This is the method that handles button presses in the UI screen on the BlackBerry.
ProcessTransaction
This method communicates from the BlackBerry to a server over the Internet using HTTP.
index.php
This is the home page of our sample server application. From here, you can launch a search for previously uploaded transactions.
db.php
Manages connection to MySQL database.
export.php
Provides an export to CSV file of uploaded transactions.
manage.php
Manages uploaded transactions. Add to this file for your own functionality.
showtransactions.php
Displays any transactions loaded for a specific identifier.
posttransaction.php
This server routine works hand in hand with ProcessTransaction on the BlackBerry to record data collected in the field.
utils.php
This file contains helper functions for managing transactions on the server.
db.sql
This script contains the data-definition language (DDL) to create the transaction table used on the server.

Blackberry basics and the JDE

Before jumping into the installation of the BlackBerry JDE and building an application, let's introduce the major components of the BlackBerry platform. Once some of the fundamentals are presented, we'll examine the JDE.

Meet the BlackBerry

Historically, BlackBerry has always been a messaging platform. Early versions of RIM's devices were glorified two-way pagers. Expanding from that humble — and important — beginning, today's BlackBerry is an integrated telephone, text, e-mail, and rich application environment, including media and GPS capabilities on newer devices. Unlike other modern devices that boast sexy touch screens and feature-packed hardware, the BlackBerry is a capable and tactile device, ideal for the power business user and the power text-messaging user.

Network communications options

All communications between a BlackBerry device and the Internet take place by going through RIM's data centers. Communication between the device and RIM is done using a secure protocol. If you have a BlackBerry, you will run under one of a few different scenarios:

BlackBerry Enterprise Server (BES)
Corporate networks employ a BES as a means to manage mobile users' devices and connect the devices to corporate e-mail servers. Communication via RIM's network and an instance of a BES is fully secure; there is no plain-text portion of this communication over the Internet.
BlackBerry Internet Service (BIS)
This is the service most consumers and small-business users employ, as it has the cheapest licensing costs and no additional hardware requirements beyond a BlackBerry device. BIS works by configuring your e-mail account(s) on RIM's Web site and auto-magically, your e-mail shows up on your BlackBerry. Communication between RIM and your device is secure, but the connection between RIM and your e-mail server may or may not be secure, depending on the kind of e-mail provider you use.
Desktop Redirector for Outlook
The redirector connects RIM's data center with a local Microsoft® Outlook® session running on a local computer. In this scenario, the Outlook program must stay logged in at all times in order for e-mail to flow to the BlackBerry device. This is not an ideal scenario for the truly mobile user who has a laptop, rather than a desktop computer. If the laptop is packed in a bag with you on the train, there is no mobile e-mail.

Running under a BES environment provides the most control and options for applications and IT policy enforcement. For example, an IT administrator can prevent users from reaching certain Internet sites, thereby restricting device use to business only. In addition, certain "push"-application capabilities are enabled with a BES. The topics in this tutorial are universally applicable regardless of the environment a particular BlackBerry operates under. The only assumption made is that a data plan allowing Internet access is permitted. Of course, if you have a BlackBerry restricted with respect to what Internet sites may be visited, you may have to convince your IT administrator to open up access to the sample application's server.

Device characteristics

There are a few physical characteristics of a BlackBerry device worth mentioning:

QWERTY keyboard
BlackBerry devices have long been distinguishable by their full QWERTY keyboard — a must-have for text-intensive mobile users. The tactile buttons are good also for keyboard shortcuts — a feature sorely lacking on devices that do not have physical buttons.
Track wheel
The track wheel is essentially a "jog dial" on the side of your BlackBerry. The track wheel is used for navigating the UI because BlackBerry devices do not feature a touch screen. The track wheel is "selectable," meaning it can be depressed to make a selection in the GUI. Pressing the track wheel is analogous to "clicking" the mouse on a desktop computer. Holding the Alt button on the keypad modifies the behavior of the track wheel within the UI. Newer devices have a track ball, which acts similarly to the track wheel.
Escape button
This button acts as a back button, moving the user back one step in the navigation.
Ribbon vs. non-Ribbon applications
The application icons on the main screen are referred to as the Ribbon. Custom applications, like the one constructed in this tutorial, reside inside the Applications folder in the Ribbon.
Bluetooth communications
In addition to the standard Bluetooth hands-free ear piece, many BlackBerry devices support the Bluetooth serial-port profile. This allows sophisticated applications to be written for a BlackBerry. Ideas include communicating with a GPS receiver, printing, or loading firmware into an embedded device, such as an appliance or vending machine.

Figure 1 highlights some of these physical characteristics.

Figure 1. BlackBerry device
BlackBerry device

Now let's examine BlackBerry application development.

BlackBerry JDE

From a software perspective, BlackBerry devices are Java-enabled and provide an excellent platform for application development. Unlike some J2ME-capable phones, where running an application feels like jumping to the other side of the phone in a "dual-boot" fashion, application launch on the BlackBerry has a natural and integrated feel. In fact, integration is so tight that third-party applications can even add custom menus to many of the core BlackBerry applications. Having a solid understanding of the Java language is helpful for building BlackBerry applications.

This tutorial focuses on using the BlackBerry JDE. There are a number of versions of the JDE available for download from the RIM Web site. These distinct versions correspond to software revisions found on BlackBerry hardware. For example, using an older version of the JDE can be a good idea when the application is aiming to work on as many devices as possible, including older devices, which may have a more-limited feature set. This might look like writing an application that does not require a camera or true GPS services. Taking a least-common denominator can be a good idea when building a commercial application because the more devices capable of running the application the more opportunity exists for product sales.

What is included?

The available development environment download packages from RIM consist of more than simply a graphical code editor and compilation tools. Resources from RIM include:

Graphical code editor
This looks similar to other programming environments offering application project management, code editing, code compiling, and debugging.
Device simulators
These enable the code, compile, and debug cycle to take place directly on the development computer. This is a great advantage over testing solely on the real device. Good coding practices suggest that testing takes place on the device before release of a product. However, using the simulator is a great time-saver during the development phase. Using simulators can also be an important part of the application-support process because a user may report an anomaly that only occurs on a particular device. For example, one application I wrote worked fine on most devices, but the 8700c demonstrated quirky behavior. Using the simulator, I was able to isolate the problem and find a solution. It's a good idea to periodically test your application on the latest device simulators as they become available. This is a cheaper alternative to purchasing every new device that hits the market. The simulator is also a convenient mechanism for documenting an application — grabbing screensshots is simple.
API reference
A convenient and detailed API reference is included in the JDE download.
MDS simulator
This software simulates the communication traffic between a real BlackBerry and the RIM network. Without the MDS simulator running, the BlackBerry device simulator is unable to communicate with hosts on the Internet.
E-mail simulator
The JDE also includes an e-mail simulator. Because so much of the operation of a BlackBerry is e-mail-related, it's a good idea to make use of the e-mail simulator. This permits applications to test e-mail-related functionality.

From a code perspective, BlackBerry applications leverage J2ME classes, as well as specially extended Application Programming Interfaces (APIs). These APIs have some overlap with the J2ME packages. However, the BlackBerry-provided classes are of great interest due to the powerful access they provide to a BlackBerry.

If your objective here is to follow along by building the sample application, please take a moment now to install a version of the BlackBerry JDE. The System requirements section includes a link to the JDE download page on RIM's Web site.


A BlackBerry application

The best way to learn is by doing, so let's jump right in and build a BlackBerry data-collection application. Each major element of the tutorial sample application is examined, including the relevant source-code snippets.

The BlackBerry Application class

This tutorial creates a single application, which will be built up in parts throughout the tutorial. The first code snippet to review is found in bb_ibm_demo.java. You can download the complete source code for this tutorial from the Download section.

Like any basic Java application, an application requires an entry point, namely main. Portions of the source file bb_ibm_demo.java are included below.

Listing 1. main method of the bb_ibm_demo.java file
//
// bb_ibm_demo.java
//
// MSI Services, Inc.
// Frank Ableson
// 973.448.0070
// fableson@msiservices.com
// code free to use for any purpose, commercial or otherwise
 

package com.msi.ibm;

// required imports
import net.rim.device.api.ui.*;

// our application class
class bb_ibm_demo extends UiApplication
{
    
    // application entry point
    public static void main(String[] args)
    {
        // create an instance of our app
        bb_ibm_demo theApp = new bb_ibm_demo();
        
        // "run" the app
        theApp.enterEventDispatcher();
    }


    // app constructor
    public bb_ibm_demo()
    {

        // create an instance of the main screen of our application
        bb_ibm_screen screen = new bb_ibm_screen();

        // make the screen visible
        pushScreen(screen); 
    }
}

The main method creates a new instance of the class named bb_ibm_demo. This class is an extension of the UiApplication class. UiApplication is found in the net.rim.device.api.ui package. The UiApplication class is a base class for all BlackBerry applications that have a UI.

The constructor of the bb_ibm_demo class creates an instance of the bb_ibm_screen class. This class is defined and implemented in bb_ibm_screen.java. Once the screen is created, it is passed to the pushScreen() method. This essentially brings the screen into view on the device.

The screen

The example application has a very basic UI. The bb_ibm_screen class extends the MainScreen class, which is a class provided by RIM that implements features common to BlackBerry applications. In addition, this class implements the Java Interface FieldChangeListener. This allows the class to react to user input in the UI elements. This topic is explained in greater detail in an upcoming section on detecting a button press.

The core UI for the sample application is created in the constructor of the class bb_ibm_screen. Before looking at the code for the creation of the UI elements, let's look at the declaration of the UI elements that are members of our class.

Listing 2. Declaration of UI elements
    // private members - these represent the "controls"
    private BasicEditField identifierfield = null;
    private BasicEditField datafield = null;
    private ButtonField submitbutton = null;
    private LabelField statusfield = null;

Each variable represents a UI element. There are two fields where text may be entered. These are the BasicEditField members. The ButtonField is used to initiate a transaction. The LabelField provides a read-only display of what is happening in the application. Let's look at the code that creates the UI for the tutorial sample application (see Listing 3). The constructor invokes the super-class constructor with a call to super(). The title of the screen is set, and a method is called to create the UI. The UI is broken out to a separate method.

Listing 3. Creating the UI for the sample application
    // constructor
    public bb_ibm_screen()
    {
        // invoke the constructor of the super class (MainScreen)
        super();
        // give our application window a title
        setTitle("BB IBM Demo App");
        // create user interface components
        createui();
    }

The layout

Looking closer at the createui method, note that each of the fields is created with a specific method call (see Listing 4). For example, the BasicEditField class presents a label, along with an entry field with a specific default value, maximum length, and a style. For a list of the available styles, examine the Field and EditField class definitions in the API Javadoc. A ButtonField is used to submit the transaction. A LabelField is also created to provide status information. Once each of these elements is instantiated, the add method is used to include the UI component on the screen. One of the very nice features of BlackBerry screens is that vertical scrolling occurs automatically without the need for complicated scrolling code. For data-collection applications that require a fair amount of screen real estate, this is a welcome feature.

Listing 4. The creatui() method
private void createui()
  {
      try
      {
      // create a field for entering the "identifier" of our transaction
      identifierfield = new BasicEditField("Identifier: ","",50, EditField.NO_NEWLINE );
      // add this field to the screen
      add(identifierfield);
      // create a field for the data of our transaction
      datafield = new BasicEditField("Data: ","",100, EditField.NO_NEWLINE );    
      // add this field to the screen
      add(datafield);
      // create a button to submit out transaction
      submitbutton = new ButtonField("Submit Transaction",ButtonField.CONSUME_CLICK);
      // tell this button who handles changes (selection)
      submitbutton.setChangeListener(this);
      // add this button to the screen
      add(submitbutton);
      // add a status label
      statusfield = new LabelField("Please enter transaction data.");
      // add label to screen
      add(statusfield);
      }
      catch (Exception e)
      {
          System.out.println("Failed to create user interface components");
      }
    }

Now that the UI has been created, it's time to look at the detection of events. Keeping in line with the Java architecture powering the BlackBerry platform, event detection is implemented through the use of one or more event-listener interfaces.

Detecting button press

There are a number of event listeners available in the BlackBerry environment. The listener of interest to this sample application is the FieldChangeListener interface. This interface provides a means for detecting changes in fields, including buttons. To make use of a FieldChangeListener, three requirements must be met. The first is the implementation of the interface's method fieldChanged(). The method is actually quite simple, requiring only two arguments — the more important being the first, which represents the field that has changed in some manner.

Listing 5. fieldChanged() method
public void fieldChanged(Field field, int Context);

The second required step is to install the listener with a call to setChangeListener(), as shown in the code snippet above. Without this method invocation, changes to the field are not processed.

The third requirement is that the argument passed to setChangeListener must be a class that contains the fieldChanged method. Another way of stating this is that the class implements the FieldChangeListener interface. In this case, the tutorial sample application's UI class (bb_ibm_screen) implements FieldChangeListener: class bb_ibm_screen extends MainScreen, which implements FieldChangeListener.

Let's examine the fieldChanged method, as shown in Listing 6.

Listing 6. The fieldChanged method
    // this method implements the FieldChangedListener Interface
    // it is used to detect when the button is selected
    // after validating that the input data is correct, it attempts to submit a 
	// transaction to the server
    public void fieldChanged(Field f, int context)
    {
        // which field was changed
        if (f == submitbutton)
        {
            // check fields....
            String id = identifierfield.getText();
            String data = datafield.getText();
            
            if (id.trim().length() == 0 || data.trim().length() == 0)
            {Dialog.alert("Please fill in all fields.");identifierfield.setFocus();return;
            }
            
            // ok, looks like we have some good data
            if (bb_ibm_transaction.ProcessTransaction(id,data) == true)
            {// transaction was submitted successfully, let's reset the GUI for easy
	// entry to another \
	fieldidentifierfield.setText("");datafield.setText("");\
	identifierfield.setFocus();statusfield.setText("Transaction Sent.");
// if you preferred to just close this application after submission, 
	// uncomment out the following line//onClose();
            }

        }
    }

The method checks to see if the field passed to the method is the Submit button. If so, the implementation proceeds to verify the input data. In this example, the code simply checks that the fields are not empty. In a more stringent application, these values might be validated against a local store of known identifiers or other input criteria. Assuming the data passes the simple validation test, the transaction is processed with a call to the ProcessTransaction method of the bb_ibm_transaction class, which is reviewed in the next section.


Data-collection applications with BlackBerry

Just what is a data-collection application anyway? Many applications fit into this category; they are all around us. Every time we sign for a package or take a picture of a house we are considering renting, we're collecting data. Oftentimes, these applications are associated with a "vertical," such as healthcare or logistics. No matter the industry; there are some design patterns and practices that are important when collecting information with a mobile device. The next section talks about what to do with the data once it has been collected, including a working Java method for processing a transaction.

What makes a good data-collection application

There are a handful of techniques that contribute to a good data-collection application. Sometimes devices go out of range, but are still capable of collecting data. An example of this is a Bluetooth-enabled piece of equipment that is in a remote location. The field-service technician carrying a BlackBerry may not have a cellular signal, but can still interact with the equipment by way of a local Bluetooth data connection. In this case, it is important that the user have the option to store (queue) data locally for transmission at a later time when back in range. Another example of local storage is for reference data used to validate data-entry fields by mobile users. During an inventory-cycle count, a reference list of items to count would be reasonable to store on the device without having a network connection.

There are, however, times when local storage is not necessary or warranted. For example, an application may require an Internet connection to a server providing important information relevant to the user at the time, such as the proximity of other users in the network. An example of this would be a networking application concerned with the availability of specific people or resources. Market data is another example where real-time data is important. We don't want to purchase pork bellies at a higher price than the market, for example.

Building the capability to store data locally is an important aspect of mobile data-collection applications. However, the techniques for storing data locally on the BlackBerry are beyond the scope of this tutorial. That said, the tutorial sample application does, in fact, collect data and needs to have something to do with it once collected. To do this, let's examine the ProcessTransaction method in the bb_ibm_transaction class, implemented in the file bb_ibm_transaction.java.

Listing 7. The ProcessTransaction method
    // this method interacts with the server
    public static boolean ProcessTransaction(String id,String data)
    {
        // default to non-success return code
        boolean ret = false;
        
        // some variables necessary for HTTP communication
        InputStream inputStream = null;
        HttpConnection httpConnection = null;


        // because many of the steps can throw an exception, wrap this method 
		// in a try/catch block
        try
        {
            
            StringBuffer returnStringBuffer = new StringBuffer();
            String returnString = new String();
            

            String desiredEncoding = "ISO-8859-1";


            URLEncodedPostData params = new URLEncodedPostData(URLEncodedPostData.
DEFAULT_CHARSET, true);
            params.append("identifier", id);
            params.append("data", data);
            
            String url = "http://ibm.msi-wireless.com/posttransaction.php?" 
+ params.toString();                   
            System.out.println(url);                                              
            //Connecting to Server
            httpConnection = (HttpConnection)Connector.open(url);
            inputStream = httpConnection.openDataInputStream();
            
            if(httpConnection.getResponseCode() == HttpConnection.HTTP_OK)
            {int ch;
            //Process Response// check header field for a specific encodingString \
contenttype = httpConnection.getHeaderField("Content-Type");if (contenttype != null){   
contenttype = contenttype.toUpperCase();   \
if (contenttype.indexOf("UTF-8") != -1)    {        desiredEncoding = "UTF-8";    }}
            // get an inputstreamreader to handle utf-8 dataInputStreamReader \
isr = new InputStreamReader(inputStream,
desiredEncoding);
while ((ch = isr.read()) != -1) { returnStringBuffer.append((char) ch);} \
	inputStream.close();httpConnection.close();inputStream = null;\
	httpConnection = null;returnString = returnStringBuffer.toString();
// examine return stringif (returnString.indexOf("SUCCESS") \
!= -1){    ret = true;}return ret;
            }
            inputStream.close();
            httpConnection.close();
            inputStream = null;
            httpConnection = null;
            //Bad Transaction.
            return ret;
        }
        catch (Exception e)
        {
            System.out.println("Error occurred in ProcessTransaction(" + id + "," 
+ data + ")\n" + e.toString());
            return ret;
        }
        finally
        {
            try
            {if (inputStream != null)    inputStream.close();if \
(httpConnection != null)    httpConnection.close();
            }
            catch (Exception ee)
            {
            }
        }
    }

The ProcessTransaction method demonstrates a number of useful techniques for communicating with a Web server. It establishes a connection and submits a URLEncoded query to a specific URL. The URLEncodedPostData takes care of formatting data as if the data were generated by a "Form Field" in a desktop browser. Note the code that examines the content type and sets up an InputStreamReader to process the data. Without this step, any data beyond the most basic of text can come across in unexpected and undesired ways. This function returns True if the Web server returns the string SUCCESS.

Building the application

Now that the relevant code snippets have been reviewed, let's jump back to the BlackBerry development environment to build the application. After loading the sample code, the BlackBerry JDE should look similar to Figure 2.

Figure 2. The BlackBerry JDE with the sample code loaded
The BlackBerry JDE with the sample code loaded

To build the application, press the F7 key. To see the output of the build process, select the Output option under the View menu or use Alt+2 (while holding the Alt key, press the number 2).

Assuming there are no errors in the code and the application has been built without errors, it's time to run the application in the BlackBerry simulator. The first step to take is to make sure that the MDS simulator is running. The MDS simulator allows the BlackBerry simulator to connect to the network, including the Internet. The MDS simulator can be started automatically if preferred. To make changes like when the MDS simulator is started (automatically or manually) and other BlackBerry simulator options, use the Preferences option in the Edit menu in the BlackBerry JDE editor, as shown below.

Figure 3. Preferences option in the BlackBerry JDE editor
Preferences option in the BlackBerry JDE editor

Hitting F5 will start the BlackBerry simulator. The tutorial sample application will not start right away. It must be started by navigating to the application's icon on the home-page application Ribbon and selecting the tutorial sample application: bb_ibm. The arrow keys on the computer simulate the track wheel, the Enter key simulates pressing the track wheel, and the escape key emulates the BlackBerry escape button.

Now that the BlackBerry side of this tutorial has been discussed, let's look at the important server-side, where data is stored and managed.


Transaction processing on the server

Without a place to store and manage collected data, the BlackBerry application would be of limited value. While a mobile data-collection application may store data only on the mobile device. In most cases, a successful mobile data-collection application will have a server-side component to complement the mobile data-collection software.

Data storage

To store data on the server, the tutorial sample application leverages the very popular open source MySQL database. A single application database table is employed: tbl_transactions. This table stores data sent by the BlackBerry application. Other management steps, including exporting and purging data leverage this same database table. The Data Definition Language for this table is found in Listing 8.

Listing 8. Data Definition Language for tbl_transactions table
CREATE TABLE 'db_ibmmsiwireless'.'tbl_transactions' (
'tid' INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'unique id',
'usercode' VARCHAR( 50 ) CHARACTER SET ascii COLLATE ascii_general_ci 
    NOT NULL COMMENT 'which user',
'datum' LONGTEXT CHARACTER SET ascii COLLATE ascii_general_ci 
    NOT NULL COMMENT 'data from tran',
'stampx' DATETIME NOT NULL COMMENT 'when transaction occurred',
PRIMARY KEY ( 'tid' ) ,
INDEX ( 'usercode' , 'stampx' ) 
) ENGINE = MYISAM CHARACTER SET ascii COLLATE ascii_general_ci

Having a database table does not solve the challenge of storing data completely. What is needed is a transaction to accept the incoming data, validate the data, as necessary, and store the transaction. There are a number of options available here. The application requires a Remote Procedure Call (RPC) of some kind. Without getting caught up in the various philosophical discussions of which RPC method is better, the tutorial is taking a simplistic approach of using URL encoded form data for transaction submission. In order to not get distracted with other (important) technologies, let's keep things simple.

An advantage of using a form-based data approach is that testing the server side can be done with a simply constructed form — no costly or complex tools are required.

Transaction processing

The transaction on the server side is implemented in another open source technology: PHP. PHP is employed because of its ease of use, its rich functionality, and its open source licensing model. Like many programming environments, breaking functionality out to separate modules or classes is a good programming style, fostering ease of maintenance and readability. Let's examine the PHP environment that implements the tutorial sample application's server side.

Listing 9. PHP transaction for the server side
db.php	
<?php
$mysql_db = "db_ibmmsiwireless";
$mysql_user = "username";
$mysql_pass = "password";
$mysql_link = mysql_connect("dbservername", $mysql_user, $mysql_pass);
mysql_select_db($mysql_db, $mysql_link);
?>

The db.php page contains database-related connectivity information. This file is included by any pages that interact with the database. Note that the use of a database platform other than MySQL would result in the db.php file contents being changed to reflect the alternate database environment.

Listing 10. Database details
posttransaction.php
<?php
require('db.php');
require('utils.php');
putTransaction($_GET['identifier'],$_GET['data'])
?>

The post-transaction.php page is very simple — it references the database settings found in db.php and loads the routines found in utils.php, which will be reviewed shortly.

Once the two require statements are processed to load the database and utility routines, respectively, this server-side script passes two data elements to a function named putTransaction. Note the syntax of $_GET[]. This demonstrates the means to access form data sent to the page from the BlackBerry (or a testing form). Note that if data were to be sent using POST, rather than GET, it would be accessed using the $_POST[] syntax.

Let's look at the putTransaction function, which is found in the file utils.php.

Listing 11. putTransaction function
function putTransaction($id,$datum)
{
global $mysql_link;

$sql = "insert tbl_transactions (usercode,datum,stampx) values ('$id','$datum',NOW())";
//print($sql);
$result = mysql_query($sql,$mysql_link);
if ($result == 1)
{
	print("SUCCESS");
}
else
{
	print("FAILED");
}
}

The putTransaction method receives two arguments: an identifier and the data to be stored, or $id and $datum, respectively. The function generates a simple SQL insert statement to populate a new row into the tbl_transactions table. Note the use of the MySQL function of NOW(). This allows a database-generated timestamp to be provided on every transaction recorded. This can be a useful tool in data-collection applications to know when a transaction was received.

Additionally, a production transaction should include a provision to guard against an SQL injection attack. This step is omitted for the sake of clarity.

If the database operation is successful, this method returns the string SUCCESS, otherwise the string FAILED. Note that this function uses the PHP print function, which means that this string is sent back directly to the client, which in the case of this tutorial sample application, is the BlackBerry application presented earlier. In the strictest sense, this is a shortcut. Functions found in utils.php should ideally return values to their callers, which would then make the decision on what to communicate back to the client. In the interest of simplicity, all of the functions return values directly to the client.

Congratulations! The transaction that started on the BlackBerry is now safely stored in a relational database on the server. Now that the data has been stored, let's look at what can be done with it.

Managing the data

Additional functions in the utils.php enable some other important features of a data collection application. The getTransactions() function is invoked from the showtransactions.php page. This allows a simple query across all stored transactions and displays the results in the browser.

Listing 12. getTransactions() function is invoked from showtransactions.php
// In file showtransactions.php:

<?
require('db.php');
require('utils.php');
require('header.php');
?>
<html>
<head>
<title>MSI Wireless Transactions</title>
</head>
<body>
<h3>Transaction List for <? print('['.$_POST['identifier'].']') 
    ?>.</h3>
<hr />
<? getTransactions($_POST['identifier']) ?>
<br>
<a href="/">Try again</a><br>
<? require('footer.php'); ?>
</body>
</html>


// In file utils.php:

function getTransactions($id) 
{
global $mysql_link;
$result = mysql_query("SELECT * from tbl_transactions where \
usercode = '$id' order by tid", $mysql_link);
  if(mysql_num_rows($result))
  {
      print("<table border=1><tr><td>Transaction 
#</td><td>Data</td><td>Time Stamp</td></tr>");
      while($row = mysql_fetch_row($result))
      {

print("<tr><td>$row[0]</td><td>$row[2]</td><td>
$row[3]</td></tr>");
      }
      print("</table>");
      print("<a target='_blank' href='export.php?id=$id'>Export Your 
Transactions</a>");
      print("<br>");
      print("<br>");
      print("<a href='manage.php?id=$id&action=remove'>Delete Your 
Transactions</a>");
      print("<br>");
  }
  else
  {
	print("There are no transactions available.");
  }
}

The file showtransactions.php is essentially a form processor for the input form found in index.php, with relevant portions show below.

Listing 13. Abbreviated showtransactions.php file
<?require ('header.php'); ?>
//
<form method="POST" action="showtransactions.php">
Your identifier:&nbsp;<input name="identifier" maxlength="50">
<input type=submit value="Look Up My Transactions">
</form><br>
//
<? require('footer.php'); ?>
</body>
</html>

Full transaction sequence

The following screenshots walk through the use of the tutorial sample application, starting with the BlackBerry application and commencing with a search on the server side to find the newly entered transactions. Entering a transaction on the BlackBerry is shown below.

Figure 4. Entering a transaction on the BlackBerry
Entering a transaction on the BlackBerry

Figure 5 shows the server side accepting a query for this transaction type. Note that the input form has the string IBM DEMO. You can enter any value you like for this field. This field corresponds to the identifier or ID field in the database table and code snippets previously introduced.

Figure 5. The server side accepting a query for the transaction shown in Figure 4
The server side accepting a query for the transaction shown in Figure 4

The showtransactions.php page calls the getTransactions function, passing in the query value, which in this case is IBM DEMO. Any transactions found in tbl_transactions matching that identifier are displayed in the resulting page, as shown below.

Figure 6. Displaying transactions in tbl_transactions table matching IBM_DEMO
Displaying transactions in tbl_transactions table matching IBM_DEMO

Data integration

An important feature of a data-collection system is the ability to export collected data for subsequent use in destination-management systems, such as a logistics package or perhaps a billing system. For example, this tutorial sample application could be adapted for use by a utility company to collect meter data from the field. The identifier would be the meter number and the data the KWH reading from the meter.

The server side implements a simplistic export function that brings the selected data into a Microsoft Excel®-readable comma-separated value (CSV) file. The server-side code that implements this function is found in export.php.

Listing 14. export function from export.php file
<?php
	header("Content-Type: application/vns.ms-excel");
	header('Cache-Control: maxage=10'); 
	header('Pragma: public');
	header('Content-Disposition: attachment; filename="'.$_GET['id'].
'_transactions.csv"');
	require('db.php');
	require('utils.php');
	$out = fopen('php://output', 'w');
	getTransactionsToCSV($out,$_GET['id']);
	fclose($out);
?>

The getTransactionsToCSV function, found in utils.php, is shown below.

Listing 15. The getTransactionsToCSV function
function getTransactionsToCSV($out,$id) 
{
global $mysql_link;
$result = mysql_query("SELECT tid,datum,stampx from \
tbl_transactions where usercode = '$id' order by tid", $mysql_link);
  if(mysql_num_rows($result))
  {
      fputcsv($out,array("Transaction #","Data","Timestamp"));
      while($row = mysql_fetch_array($result,MYSQL_NUM))
      {
	fputcsv($out,$row);
      }
  }
}

This server-side functionality is freely available for you to use for testing out your BlackBerry data-collection applications (see System requirements).


Next steps

There are a few topics yet to be addressed before this tutorial can be complete. This tutorial sample application is missing one crucial step required for running applications on a real BlackBerry. Additionally, there are two nice-to-have features in any mobile data-collection application that need to be addressed. And the topic of open source licensing is touched upon before wrapping up.

Controlled APIs

First, let's discuss the required step for loading an application on a real BlackBerry. There are a number of classes in the BlackBerry API that require code signing. These classes are referred to as Controlled APIs. This means that RIM views the use of these classes as sensitive and, therefore, requires that you sign the application with a RIM-supplied developer key. This allows RIM to identify the author of an application. Why is this important? Let's say someone authors an application that sends out spam or otherwise is a misbehaving citizen. The step of requiring a signature makes the developer think twice before releasing such an application. Additionally, RIM can revoke a developer key if necessary, thereby hampering the rogue developer's ability to release these kinds of applications. Of course, building rogue applications is not the intent here. However it is important to discuss because this step is require before loading an application to a real device. Unfortunately, this step is not free, but the fee ($20 USD) is not excessive.

To obtain a developer key, you must apply at RIM's Web site. See Resources for the developer key registration URL.

Once a developer key is installed in the JDE, signing the application is straightforward.

Signing the application

After successfully building the application, select the Request Signatures option beneath the Build menu.

Figure 7. Selecting the Request Signatures option
Selecting the Request Signatures option

When the Signature Tool screen launches, each code module is listed, along with a Category field indicating whether the particular module requires signing. Enter the private-key password established when the developer key was established to proceed with the signing operation.

Figure 8. Entering the private key password
Entering the private key password

Once the signing step is complete, the Status column will indicate that the modules have been signed.

Figure 9. Status column indicates modules have been signed
Status column indicates modules have been signed

At this point, the application is ready to be installed on the device. Applications may be installed via a BlackBerry Enterprise Server, the BlackBerry Desktop Manager, or using an Over The Air method. For more information about loading an application on a real device, see Resources.

Error handling

Error handling is omitted from this tutorial for the sake of brevity and clarity. Of course, any production-ready code should have a healthy dose of error handling and instructions for the user of the application in the event that something goes awry.

Queuing

This topic was touched upon briefly, but it warrants further mention. There are scenarios where an application will need to queue data. The reasons may involve data requirements of gathering data in batches and submitting them with summary information — a physical-inventory application, for example. Alternatively, there may be connectivity issues where transactions cannot be sent immediately upon collection. While this topic was not expressly implemented in the tutorial sample application, queuing strategy should not be overlooked in a real-world data-collection application.

Open source licensing

Taking an idea from concept to a licensed open source application is no small feat. This tutorial sample is a good starting point for a more comprehensive data-collection platform, but there is more work to be done. One next step could be adding location-based information (GPS data, for example) or perhaps bolting on a Bluetooth-capable barcode scanner for gathering inventory data in the field. Regardless of the next technical feature to add to this application, the choosing of an appropriate open source license needs to be addressed. The pros and cons of an open source license selection is beyond the scope of this tutorial, but it needs some thought for any serious open source product. The reference section contains a link to a site that aggregates a number of open source licenses. If you are serious about building an open source application, put some thought into choosing an appropriate license for your BlackBerry application.


Summary

This tutorial has introduced the BlackBerry platform and demonstrated developing mobile data-collection applications with open source technologies, including Java, PHP, and MySQL. The basics of BlackBerry UI and communications were introduced, along with a simple, yet powerful server side implemented in open source staples PHP and MySQL. Leveraging these open source technologies opens up a world of software creativity far exceeding custom ringtones and text messaging. One might even say that the market for open source BlackBerry applications with Java is ripe for the picking.


Downloads

DescriptionNameSize
Java codeos-blackberry-code.zip17KB
PHP and SQL codeos-blackberry-serverside.zip4KB

Resources

Learn

  • Be sure to read Part 2 and Part 3 of this series.
  • BlackBerry Desktop Software: Research In Motion (RIM) offers a full range of helpful user and administrator information on BlackBerry Desktop Software, including more about installing software via the Desktop Manager.
  • You'll find articles about every aspect of Java programming in the developerWorks Java technology zone.
  • OpenSource.org presents a catalog of the most popular open source licenses.
  • PHP.net is the central resource for PHP developers.
  • Check out the "Recommended PHP reading list."
  • Browse all the PHP content on developerWorks.
  • Expand your PHP skills by checking out IBM developerWorks' PHP project resources.
  • To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
  • Using a database with PHP? Check out the Zend Core for IBM, a seamless, out-of-the-box, easy-to-install PHP development and production environment that supports IBM DB2 V9.
  • Stay current with developerWorks' Technical events and webcasts.
  • Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
  • Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
  • Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=376390
ArticleTitle=Create BlackBerry applications with open source tools, Part 1: Laying the groundwork
publish-date=08192008