X

Your session is about to expire in !



Stay Signed In Ignore
X

Sorry! Your session has expired.



(open topic page)

The Developer Support team often sees cases in which Content Providers report that their app does not load on a particular device. In most of these cases, the source of the problem is usually coding errors in how the device handles the JAD and Manifest files during app download and installation.

To help avoid errors in your MIDP application, keep the following rules in mind:

JAD and Manifest file attributes must be properly matched. Attributes that are mismatched will cause errors in the installation process. Manifest and Java Application Descriptor (JAD) files must contain the following attributes:

  • MIDlet-<n> for each MIDlet
  • MicroEdition-Profile
  • MicroEdition-Configuration

JAD and Manifest files must not contain attributes with empty values.

MIDlet-Permissions must be in order. Don't call an API that is not declared, and don't call an API that you are not certified to have. Use the MIDlet-Permissions-Opt attribute for an API that you would like to access. If the API is not available, this call won't affect your app.

Your application must have the appropriate signed certificate to allow access to restricted APIs. Here are the JAD Certificate attributes:

  • MIDlet-Certificate-1-1 :: The certificate issued by the signing authority
  • MIDlet-Jar-RSA-SHA1 :: The signer's private key
  • MIDlet-Certificate-1-2 :: An intermediate certificate (if your certificate authority gave you back a certificate as part of a multi-part certificate chain)

For more information, refer to Java Application Security. You can also read more about MIDP 2.0 attributes on the Java ME site.

Updated: 09/02/2011 | Created: 05/19/2010
(open topic page)

AT&T Developer Support recommends using OTA (over the air) to download and install your JavaME apps instead of side-loading (i.e., using a USB cable tethered between your computer and the device).

The biggest reason to avoid side-loading is that the device's JVM will place the app in the MIDP 1.0 sandbox. This will prevent your app from accessing MIDP 2.0 JSRs, which will leave your app without many types of robust functionality.

Moreover, there are certain types of bugs that are only discoverable when apps are OTA-loaded, rather than side-loaded, onto devices. Make sure to test the user experience in OTA-loaded versions of your app to avoid user complaints about bugs that were not discovered pre-launch.

Last but not least, AT&T has found that on some devices, an AT&T-signed Java ME app will not install via side-loading; the device does not recognize the signature, and there is no workaround to install the app.

Therefore, always use OTA to deliver your Java ME apps and games. Here's the MIME type you need to configure on your server in order to deliver apps OTA:

text/vnd.sun.j2me.app-descriptor jad
application/java-archive jar

Updated: 09/02/2011 | Created: 05/19/2010
(open topic page)

In today's marketplace, mobile devices are required to perform many of the same operations as the traditional laptop or desktop. Many mobile applications today are network-aware or have access to sensitive user data such as documents or the information in phone books and calendars. To safeguard MIDP 2.0 has created the concept of protected domains. These domains have the same names as the functions or APIs that fall under each domain's umbrella. To enable the usage of these secure functions, a developer must request the domain within the JAD and .MF Manifest file. Java ME requires the use of the following parameters:

MIDlet-Permissions: parameter denotes functionality that is a necessary part of the application

and

MIDlet-Permissions-opt: parameter denotes functionality that may be required by the application during runtime, but is not vital to the operation

Java ME has a two-step installation process. During installation, the JAD parameters are reviewed. At this point, the Application Manager will look at request permissions and determine if such permissions can be granted to the application. If such permissions cannot be granted, the Application Manager will refuse to install the application if the functionality is required. Optional permissions not granted will still allow installation. This check is completed in order to keep the user from incurring data charges for the much larger JAR file.

If all permissions are granted, or defined as optional, the Application Manager will proceed to JAR delivery, at which time it will take the next step and review the requested permissions within the Manifest File. Once again, if such permissions cannot be granted, the Application Manager will refuse to install the application. Optional permissions not granted will still allow installation.

Secure functionality not requested at install time is denied during runtime by throwing a security error, or defaulting to access denied prompting behavior.

HTTP connectivity falls within the javax.microedition.io.Connector.http domain. In order to request this functionality, the following parameters should be added to JAD and Manifest at build time:

MIDlet-Permissions: javax.microedition.io.Connector.http

Without this permission, the application will most likely install, but networking connectivity may be arbitrarily denied at runtime of the application.

Please note that prompting behavior will vary depending on the Certificate used to sign the application. Unsigned builds will default to the MIDP 1.0 security policies. For Full information on AT&T specifications, please refer to Java Signing Specification. For Specific JSR documentation with the JCP.

For more information, please refer to the Sun Microsystems article Understanding MIDP 2.0's Security Architecture.

Updated: 09/02/2011 | Created: 05/19/2010
(open topic page)

One of the major challenges when deploying an application is maintaining all of the separate builds for each device. A build constitutes a unique JAD/JAR combination. This becomes much more difficult after an application is signed. The signature inside the JAD file references a secure hash of the JAR file. If any aspect of the file changes, even a simple text string, the secure hash will change, and, therefore, an application would need to be resigned. If you add demos, locality builds, or different versions for a particular device, the number of builds could increase exponentially.

One way to manage a large number of builds is to add flexibility into your deployment model. Instead of hard-coding application parameters, package applications in a way that allows versatility.

You can accomplish this by using custom JAD parameters. Although the JAR file cannot be altered once the JAD/JAR pair is signed, the JAD file, being a text-based file, can be altered as long as the required parameters pointing to original JAR file are not changed. The certificate data, the secure hash, and application information should not be altered.

You can manually build multiple versions of JADs for deployment by either opening them in a text editor and adding a line, or using a server-based programming language such as PHP, ASP, or JSP to inject a line into the JAD file. If you decide on the server- injection method, please make sure to use the appropriate mime-type: 'text/vnd.sun.j2me.app-descriptor.'

For example:

An application contains code to display the Subscriber's ID.

Add a custom parameter to the JAD file:

subID: inject variable using php, jsp, asp, etc.

Within the application code, request the value:

String subID = getAppProperty("subID");

The variable subID can now be used within the code; this will work whenever a mutable value is needed.

Please note: when manually creating a file for deployment, follow all relevant JAD rules and be aware of supported characters. Please do not leave any metadata, non-supported characters, blank entries, or code segments within the JAD file. If you do, the file will fail on download.

For specific documentation, please refer to JSR-118. For more information, please refer to Sun's article, Retrieving Midlet Attributes.

Updated: 09/02/2011 | Created: 05/19/2010
(open topic page)

The entire telecommunications industry is moving toward enabling security through the use of electronic certificates. Web sites rely on certificates to protect the privacy of their e-commerce transactions, and operating systems are using code-signing certificates to identify the source of packages and assign rights.

The major question asked is, "How does code signing help my customers?" The first thing that it does is ensure that customers are getting what they expect to download. When an application is signed, it cannot be changed in any way without invalidating that signing event. The customer knows that the application has come directly from the source without any tampering.

It is a simple task to create a fake application by using the graphics, text, and media from a company and then packaging a convincing skinned application that appears to be from that company. Without security in place to block access to critical areas such as personal data or network access, a consumer may be exploited because of the trust that the consumer had in a company's name. In the mobile industry, where the names of providers mean so much, it is imperative to do everything to protect these names and the trust that the consumer holds in these companies.

Once the source is known and trusted, certain privileges can be extended to your customers. All application platforms supporting security models will prompt the user when the source of the application is unsigned; by signing, however, these simple "untrusted" messages will disappear. This is good practice to follow even for applications that do not require secure APIs to function correctly. The message goes away at install, and customers seamlessly access the product.

The final benefit that can be offered after trust is established is a limit to prompting behavior. An unsigned application will prompt the customer with every network action, whereas a third-party signed application will only prompt once during the session.

When used correctly, code signing can protect your name and your customers' privacy.

J2ME Bluetooth GPS Guide

Source: Amitava Bhattacharyya, Development Lead, TeleNav. Inc.

Bluetooth API JSR-82

The Java APIs for Bluetooth define the following package that depends on the CLDC javax.microedition.io package:

  • javax.bluetooth: core Bluetooth API

The above package is a separate optional package, which means that a CLDC implementation can include either package or both. MIDP-enabled devices are expected to be the kind of devices to incorporate this specification.

Application Programming

The anatomy of a Bluetooth application has five parts: stack initialization, device management, device discovery, service discovery, and communication.

Stack Initialization

The Bluetooth stack is responsible for controlling the Bluetooth device. The initialization process comprises a number of steps whose purpose is to get the device ready for wireless communication.

Device Management

The Java Bluetooth APIs contain the classes LocalDevice and RemoteDevice, which provide the device-management capabilities defined in the Generic Access Profile. LocalDevice depends on the javax.bluetooth.DeviceClass class to retrieve the device's type and the kinds of services it offers. The RemoteDevice class represents a remote device (a device within a range of reach) and provides methods to retrieve information about the device, including its Bluetooth address and name. The following code snippet retrieves that information for the local device:

...

// retrieve the local Bluetooth device object

LocalDevice local = LocalDevice.getLocalDevice();

// retrieve the Bluetooth address of the local device

String address = local.getBluetoothAddress();

// retrieve the name of the local Bluetooth device

String name = local.getFriendlyName();

...

You can get the same information about a remote device:

...

// retrieve the device that is at the other end of

// the Bluetooth Serial Port Profile connection,

// L2CAP connection, or OBEX over RFCOMM connection

RemoteDevice remote =

    RemoteDevice.getRemoteDevice(

        javax.microedition.io.Connection c);

// retrieve the Bluetooth address of the remote device

String remoteAddress = remote.getBluetoothAddress();

// retrieve the name of the remote Bluetooth device

String remoteName = local.getFriendlyName(true);

...

The RemoteDevice class also provides methods to authenticate, authorize, or encrypt data transferred between local and remote devices.

Device Discovery

Because wireless devices are mobile they need a mechanism that allows them to find other devices and gain access to their capabilities. The core Bluetooth API's DiscoveryAgent class and DiscoveryListener interface provide the necessary discovery services.

A Bluetooth device can use a DiscoveryAgent object to obtain a list of accessible devices, in any of three ways:

The DiscoveryAgent.startInquiry method places the device into an inquiry mode. To take advantage of this mode, the application must specify an event listener that will respond to inquiry-related events. DiscoveryListener.deviceDiscovered is called each time an inquiry finds a device. When the inquiry is completed or canceled, DiscoveryListener.inquiryCompleted is invoked.

If the device doesn't wish to wait for devices to be discovered, it can use the DiscoveryAgent.retrieveDevices method to retrieve an existing list. Depending on the parameter passed, this method will return either a list of devices that were found in a previous inquiry, or a list of pre-known devices that the local device has told the Bluetooth Control Center it will contact often.

These three code snippets demonstrate the various approaches:

...

// retrieve the discovery agent

DiscoveryAgent agent = local.getDiscoveryAgent();

// place the device in inquiry mode

boolean complete = agent.startInquiry();

...

...

// retrieve the discovery agent

DiscoveryAgent agent = local.getDiscoveryAgent();

// return an array of pre-known devices

RemoteDevice[] devices =

   agent.retrieveDevices(DiscoveryAgent.PREKNOWN);

...

...

// retrieve the discovery agent

DiscoveryAgent agent = local.getDiscoveryAgent();

// return an array of devices found in a previous inquiry

RemoteDevice[] devices =

    agent.retrieveDevices(DiscoveryAgent.CACHED);

...

Service Discovery

Once the local device has discovered at least one remote device, it can begin to search for available services—Bluetooth applications it can use to accomplish useful tasks. Because service discovery is much like device discovery, DiscoveryAgent also provides methods to discover services on a Bluetooth server device, and to initiate service-discovery transactions. Note that the API provides mechanisms to search for services on remote devices, but not for services on the local device.

Communication

For a local device to use a service on a remote device, the two devices must share a common communications protocol. So that applications can access a wide variety of Bluetooth services, the Java APIs for Bluetooth provide mechanisms that allow connections to any service that uses RFCOMM, L2CAP, or OBEX as its protocol. If a service uses another protocol (such as TCP/IP) layered above one of these protocols, the application can access the service, but only if it implements the additional protocol in the application, using the CLDC Generic Connection Framework.

Serial Port Profile

The RFCOMM protocol, which is layered over the L2CAP protocol, emulates an RS-232 serial connection. The Serial Port Profile (SPP) eases communication between Bluetooth devices by providing a stream-based interface to the RFCOMM protocol. Some capabilities and limitations to note:

  • Two devices can share only one RFCOMM session at a time.
  • Up to 60 logical serial connections can be multiplexed over this session.
  • A single Bluetooth device can have at most 30 active RFCOMM services.
  • A device can support only one client connection to any given service at a time.

For a server and client to communicate using the Serial Port Profile, each must perform a few simple steps.

As the following code snippet demonstrates, the server must:

  1. Construct a URL that indicates how to connect to the service, and store it in the service record
  2. Make the service record available to the client
  3. Accept a connection from the client
  4. Send and receive data to and from the client

The URL placed in the service record may look something like:

btspp://102030405060740A1B1C1D1E100:5

This says that a client should use the Bluetooth Serial Port Profile to establish a connection to this service, which is identified with server channel 5 on a device whose address is 102030405060740A1B1C1D1E100.

...

// assuming the service UID has been retrieved

String serviceURL =

    "btspp://localhost:"+serviceUID.toString());

// more explicitly:

String ServiceURL =

    "btspp://localhost:10203040607040A1B1C1DE100;name=SPP

        Server1";

try {

    // create a server connection

    StreamConnectionNotifier notifier =

      (StreamConnectionNotifier) Connector.open(serviceURL);

    // accept client connections

    StreamConnection connection = notifier.acceptAndOpen();

    // prepare to send/receive data

    byte buffer[] = new byte[100];

    String msg = "hello there, client";

    InputStream is = connection.openInputStream();

    OutputStream os = connection.openOutputStream();

    // send data to the client

    os.write(msg.getBytes());

    // read data from client

    is.read(buffer);

    connection.close();

} catch(IOException e) {

  e.printStackTrace();

}

...

At the other end, as the next code snippet shows, to set up an RFCOMM connection to a server the client must:

  1. Initiate a service discovery to retrieve the service record
  2. Construct a connection URL using the service record
  3. Open a connection to the server
  4. Send and receive data to and from the server

...

// (assuming we have the service record)

// use record to retrieve a connection URL

String url =

    record.getConnectionURL(

        record.NOAUTHENTICATE_NOENCRYPT, false);

// open a connection to the server

StreamConnection connection =

    (StreamConnection) Connector.open(url);

// Send/receive data

try {

    byte buffer[] = new byte[100];

    String msg = "hello there, server";

    InputStream is = connection.openInputStream();

    OutputStream os = connection.openOutputStream();

    // send data to the server

    os.write(msg.getBytes);

    // read data from the server

    is.read(buffer);

    connection.close();

} catch(IOException e) {

  e.printStackTrace();

}

...

How to read GPS data from Bluetooth stream

Code snippet

readBluetoothBuffer()

{

data = readAllAvailableBytes()

if (data.length == 0)

Bluetooth connection not there

else

Bluetooth seems OK

bytesRead = readBytes();

if (no bytesRead)

read error

else

START Loop

find newLine()

{

                    //figure out whether it's RMC or GGA

                    String candidate = readBuffer

                   

                    //figure out whether RMC or GGA

                    if (candidate is $GPRMC....)

                   {

                        Store candidate as RMC

                    }

                    else if (candidate is $GPGGA)

                    {

Store candidate as GGA

                    }

            }

            END Loop

}

Common NMEA Sentence types

The following information describes the NMEA-0183 sentences transmitted by TeleType GPS receivers.

Sentence Description
$GPGGA Global positioning system fixed data
$GPGLL Geographic position - latitude / longitude
$GPGSA GNSS DOP and active satellites
$GPGSV GNSS satellites in view
$GPRMC Recommended minimum specific GNSS data
$GPVTG Course over ground and ground speed
Caveat on this Document

This document is based upon my personal experience, knowledge and several documents freely available on the Internet.

Updated: 09/02/2011 | Created: 05/20/2010
(open topic page)

With MIDP 2.0, devices often have limited resources. Because these devices do not possess native libraries for displaying XML, HTML or xHTML code, we have found that it is often easier to use the device browser to enable Web-based browsing sessions than to have the Java application scrape the code. Invoking Platform Services in a MIDP 2.0 Java application allows a request to the Web browser as well as to additional external services like the telephone dialer or a downloadable resource. The Platform Request is a MIDP2.0 non-blocking API that will take into account device resources. This API is available on most MIDP 2.0 devices including Nokia, Motorola, and Sony Ericcson.

To access a Web browser within your Java application, try this sample code:

//Code Snippet
private void openBrowser(String URL) {
try {
if ( platformRequest(URL) ) {

//If true application
//needs to close prior
//to opening browser.
//Add any clean up code here, //such as warnings that //application will terminate, //garbage collection, and //saving state data. destroyApp(false);
notifyDestroyed(); } else { //If false application //does not need to close //prior to launch of browser.
//Handle any pause information //at this point because the //application will lose focus } //Clean up }
catch(ConnectionNotFoundException e) {                     //Error is thrown if connection is not available } } //End Code Snippet

For more information on Platform Request, read Invoking Platform Services in MIDP 2.0 on the Sun Developer Network.

Updated: 09/02/2011 | Created: 05/20/2010
(open topic page)

Source: Amitava Bhattacharyya, Development Lead, TeleNav. Inc.

Bluetooth API JSR-82

The Java APIs for Bluetooth define the following package that depends on the CLDC javax.microedition.io package:

  • javax.bluetooth: core Bluetooth API

The above package is a separate optional package, which means that a CLDC implementation can include either package or both. MIDP-enabled devices are expected to be the kind of devices to incorporate this specification.

Application Programming

The anatomy of a Bluetooth application has five parts: stack initialization, device management, device discovery, service discovery, and communication.

Stack Initialization

The Bluetooth stack is responsible for controlling the Bluetooth device. The initialization process comprises a number of steps whose purpose is to get the device ready for wireless communication.

Device Management

The Java Bluetooth APIs contain the classes LocalDevice and RemoteDevice, which provide the device-management capabilities defined in the Generic Access Profile. LocalDevice depends on the javax.bluetooth.DeviceClass class to retrieve the device's type and the kinds of services it offers. The RemoteDevice class represents a remote device (a device within a range of reach) and provides methods to retrieve information about the device, including its Bluetooth address and name. The following code snippet retrieves that information for the local device:

...

// retrieve the local Bluetooth device object

LocalDevice local = LocalDevice.getLocalDevice();

// retrieve the Bluetooth address of the local device

String address = local.getBluetoothAddress();

// retrieve the name of the local Bluetooth device

String name = local.getFriendlyName();

...

You can get the same information about a remote device:

...

// retrieve the device that is at the other end of

// the Bluetooth Serial Port Profile connection,

// L2CAP connection, or OBEX over RFCOMM connection

RemoteDevice remote =

    RemoteDevice.getRemoteDevice(

        javax.microedition.io.Connection c);

// retrieve the Bluetooth address of the remote device

String remoteAddress = remote.getBluetoothAddress();

// retrieve the name of the remote Bluetooth device

String remoteName = local.getFriendlyName(true);

...

The RemoteDevice class also provides methods to authenticate, authorize, or encrypt data transferred between local and remote devices.

Device Discovery

Because wireless devices are mobile they need a mechanism that allows them to find other devices and gain access to their capabilities. The core Bluetooth API's DiscoveryAgent class and DiscoveryListener interface provide the necessary discovery services.

A Bluetooth device can use a DiscoveryAgent object to obtain a list of accessible devices, in any of three ways:

The DiscoveryAgent.startInquiry method places the device into an inquiry mode. To take advantage of this mode, the application must specify an event listener that will respond to inquiry-related events. DiscoveryListener.deviceDiscovered is called each time an inquiry finds a device. When the inquiry is completed or canceled, DiscoveryListener.inquiryCompleted is invoked.

If the device doesn't wish to wait for devices to be discovered, it can use the DiscoveryAgent.retrieveDevices method to retrieve an existing list. Depending on the parameter passed, this method will return either a list of devices that were found in a previous inquiry, or a list of pre-known devices that the local device has told the Bluetooth Control Center it will contact often.

These three code snippets demonstrate the various approaches:

...

// retrieve the discovery agent

DiscoveryAgent agent = local.getDiscoveryAgent();

// place the device in inquiry mode

boolean complete = agent.startInquiry();

...

...

// retrieve the discovery agent

DiscoveryAgent agent = local.getDiscoveryAgent();

// return an array of pre-known devices

RemoteDevice[] devices =

   agent.retrieveDevices(DiscoveryAgent.PREKNOWN);

...

...

// retrieve the discovery agent

DiscoveryAgent agent = local.getDiscoveryAgent();

// return an array of devices found in a previous inquiry

RemoteDevice[] devices =

    agent.retrieveDevices(DiscoveryAgent.CACHED);

...

Service Discovery

Once the local device has discovered at least one remote device, it can begin to search for available services - Bluetooth applications it can use to accomplish useful tasks. Because service discovery is much like device discovery, DiscoveryAgent also provides methods to discover services on a Bluetooth server device, and to initiate service-discovery transactions. Note that the API provides mechanisms to search for services on remote devices, but not for services on the local device.

Communication

For a local device to use a service on a remote device, the two devices must share a common communications protocol. So that applications can access a wide variety of Bluetooth services, the Java APIs for Bluetooth provide mechanisms that allow connections to any service that uses RFCOMM, L2CAP, or OBEX as its protocol. If a service uses another protocol (such as TCP/IP) layered above one of these protocols, the application can access the service, but only if it implements the additional protocol in the application, using the CLDC Generic Connection Framework.

Serial Port Profile

The RFCOMM protocol, which is layered over the L2CAP protocol, emulates an RS-232 serial connection. The Serial Port Profile (SPP) eases communication between Bluetooth devices by providing a stream-based interface to the RFCOMM protocol. Some capabilities and limitations to note:

  • Two devices can share only one RFCOMM session at a time.
  • Up to 60 logical serial connections can be multiplexed over this session.
  • A single Bluetooth device can have at most 30 active RFCOMM services.
  • A device can support only one client connection to any given service at a time.

For a server and client to communicate using the Serial Port Profile, each must perform a few simple steps.

As the following code snippet demonstrates, the server must:

  1. Construct a URL that indicates how to connect to the service, and store it in the service record
  2. Make the service record available to the client
  3. Accept a connection from the client
  4. Send and receive data to and from the client

The URL placed in the service record may look something like:

btspp://102030405060740A1B1C1D1E100:5

This says that a client should use the Bluetooth Serial Port Profile to establish a connection to this service, which is identified with server channel 5 on a device whose address is 102030405060740A1B1C1D1E100.

...

// assuming the service UID has been retrieved

String serviceURL =

    "btspp://localhost:"+serviceUID.toString());

// more explicitly:

String ServiceURL =

    "btspp://localhost:10203040607040A1B1C1DE100;name=SPP

        Server1";

try {

    // create a server connection

    StreamConnectionNotifier notifier =

      (StreamConnectionNotifier) Connector.open(serviceURL);

    // accept client connections

    StreamConnection connection = notifier.acceptAndOpen();

    // prepare to send/receive data

    byte buffer[] = new byte[100];

    String msg = "hello there, client";

    InputStream is = connection.openInputStream();

    OutputStream os = connection.openOutputStream();

    // send data to the client

    os.write(msg.getBytes());

    // read data from client

    is.read(buffer);

    connection.close();

} catch(IOException e) {

  e.printStackTrace();

}

...

At the other end, as the next code snippet shows, to set up an RFCOMM connection to a server the client must:

  1. Initiate a service discovery to retrieve the service record
  2. Construct a connection URL using the service record
  3. Open a connection to the server
  4. Send and receive data to and from the server

...

// (assuming we have the service record)

// use record to retrieve a connection URL

String url =

    record.getConnectionURL(

        record.NOAUTHENTICATE_NOENCRYPT, false);

// open a connection to the server

StreamConnection connection =

    (StreamConnection) Connector.open(url);

// Send/receive data

try {

    byte buffer[] = new byte[100];

    String msg = "hello there, server";

    InputStream is = connection.openInputStream();

    OutputStream os = connection.openOutputStream();

    // send data to the server

    os.write(msg.getBytes);

    // read data from the server

    is.read(buffer);

    connection.close();

} catch(IOException e) {

  e.printStackTrace();

}

...

How to read GPS data from Bluetooth stream

Code snippet

readBluetoothBuffer()

{

data = readAllAvailableBytes()

if (data.length == 0)

Bluetooth connection not there

else

Bluetooth seems OK

bytesRead = readBytes();

if (no bytesRead)

read error

else

START Loop

find newLine()

{

                    //figure out whether it's RMC or GGA

                    String candidate = readBuffer

                   

                    //figure out whether RMC or GGA

                    if (candidate is $GPRMC....)

                   {

                        Store candidate as RMC

                    }

                    else if (candidate is $GPGGA)

                    {

Store candidate as GGA

                    }

            }

            END Loop

}

Common NMEA Sentence types

The following information describes the NMEA-0183 sentences transmitted by TeleType GPS receivers.

Sentence Description
$GPGGA Global positioning system fixed data
$GPGLL Geographic position - latitude / longitude
$GPGSA GNSS DOP and active satellites
$GPGSV GNSS satellites in view
$GPRMC Recommended minimum specific GNSS data
$GPVTG Course over ground and ground speed
Caveat on this Document

This document is based upon my personal experience, knowledge and several documents freely available on the internet.

Updated: 09/02/2011 | Created: 05/24/2010
(open topic page)

JSR 211, or the Content Handler API (CHAPI), lets you specify MIDlets as content handlers for one or more specific file types. It enables MIDlet invocation from a variety of sources, including a MIDlet, a browser, or an SMS message. AT&T is requiring JSR 211 support in all mid-range and high-end devices coming down the pipeline.

As you're getting started with JSR 211, it's important to be aware that you can utilize the system property microedition.chapi.version to determine whether or not CHAPI is implemented in the system, and if so, what the version number is.

The code resides in the javax.microedition.content package and is fairly straightforward to use. You can register your MIDlet as a content handler in one of two ways: either by using .jad attributes or by registering dynamically in Java.

Using .jad attributes is called a .jad register, and that is the focus of this Tech Tip. (We'll cover MIDlet registers in the next part of this Tech Tip series of Tech Tips.)

To set up your MIDlet as a content handler, you can include these .jad attributes, but only the first one, MicroEdition-Handler-<n>, is required.

  • MicroEdition-Handler-<n>: <classname>, <type(s)>, <suffix(es)>, <action(s)>, <locale(s)> These attributes describe the handlers included in the MIDlet Suite. The arguments are the name of the MIDlet responsible for handling the content, the supported MIME-types, the supported suffixes, the supported actions (such as "open" or "edit"), and the locales.
  • MicroEdition-Handler-<n>-<locale>: <localized action names> This .jad attribute stores the descriptive names of the actions. Applications can retrieve these names using the ActionNameMap class. The list is typically useful for exhibition on the user interface. The locale suffix associates different languages (en-US, br-PT, etc.) and enables the handler to be globalized.
  • MicroEdition-Handler-<n>-ID: <ID> This attribute specifies the unique identifier of this content handler package on the device. You don't have to supply the identifier, because the underlying implementation should create it.
  • MicroEdition-Handler-<n>-Access: <ID(s)> This attribute controls the access and visibility of the content handler. It contains a list of the IDs of content handlers or applications that are allowed access and visibility into the content handler. If this attribute is omitted, all applications will be allowed access and visibility into the content handler.

Here's a little example demonstrating how you could set up a MIDlet to be a .png content handler:

MicroEdition-Handler-1: example.imageviewer.ImageViewer, image/png, .png, open, en-US fr
MicroEdition-Handler-1-en-US: Open
MicroEdition-Handler-1-fr: Voir
MicroEdition-Handler-1-ID: com.sun.example.imageviewer
MicroEdition-Handler-1-Access: com.sun.example
Updated: 09/02/2011 | Created: 10/22/2010
(open topic page)

JSR 256, or the Mobile Sensor API, enables Java apps to interface with many of the sensors on modern devices most notably the accelerometer. JSR 256 allows a device's JVM to hook into other sensors too, including a microphone, heart rate monitor, magnetometer, thermometer, network field intensity monitor, battery charge monitor, and so on. AT&T is now requiring JSR 256 support in all Java-enabled devices in the pipeline.

The code resides in the javax.microedition.sensor and javax.microedition.sensor.control packages. JSR 256 is fairly straightforward to use and enables the following mobile sensor operations:
  • Sensor detection or discovery
  • Sensor activation
  • Sensor calibration
  • Date capture
  • Sensor deactivation
The following code sample demonstrates how you can use this package to get data from the accelerometer:

//Sensor discovery
SensorInfos[] si = SensorManager.findSensors("acceleration", SensorInfo.CONTEXT_TYPE_USER );

//Sensor activation
SensorConnection sensor = (SensorConnection) Connector.open( si[0].getURL() );

//Data capture indicating size of buffer
sensor.setDataListener( this, 10 );

//Sensor deactivation
sensor.removeDataListener();
sensor.close();

This asynchronous method of getting the data will require that you implement the DataListener interface and the dataReceived() method. The second value in setDataListener() represents the number of data values that should be collected before sending out an event to the DataListener. Using a low value here will provide faster performance, but using a large value enables you to filter out outlying values.

Sensor deactivation should be performed when your MIDlet no longer needs the sensor.

Updated: 09/02/2011 | Created: 08/18/2010
(open topic page)

The Limited Capability Device User Interface (LCDUI) package in Java ME provides a powerful set of prebuilt user interface elements that makes simple form-driven apps a breeze to develop. LCDUI comes in the package javax.microedition.lcdui and always uses a single Display object as its active object. These displayable objects include items such as Form, List, Textbox, and Alert. LCDUI uses commands for user input, and the device controls the placement of these commands. Examples of common commands include Exit, Back, Item, and Screen.

Here's a simple example displaying the customary "Hello World!" on a form in a StringItem:

packagecom.att;
importjavax.microedition.midlet.*;
importjavax.microedition.lcdui.*;

public class MIDletHelloWorld extends MIDlet {

public MIDletHelloWorld(){}

private Display display;
private Form form;
private StringItem StringHelloWorld;

publicvoid startApp(){
//Create StringItem and Form.
StringHelloWorld = new StringItem("Hello World!", "");
form = new Form(null, new Item[]{ StringHelloWorld});

//Get the current display and set the form on the display.
display = Display.getDisplay(this);
display.setCurrent( form );
}

publicvoid pauseApp(){}

publicvoid destroyApp( boolean unconditional ){}
}

Updated: 09/02/2011 | Created: 08/18/2010
(open topic page)

Java Commands provide an easy and quick way to get user input from a MIDlet that is using LCDUI. When utilizing the Command class, it is important to note that the Commands only capture the intent of the action, not the action itself. The action itself is captured in a CommandListener.

Commands can be utilized in any UI element that is set up to activate an action—think buttons, menu items, radio buttons, etc. Commands contain four parameters: a short label, a long label (optional), a type, and a priority. The label parameters are self-explanatory. The type parameter specifies what action a Command should initialize. The standard types are back, cancel, exit, help, item, OK, screen, and stop. The priority parameter describes the Command's importance relative to other Commands.

Here is a small sample MIDlet which demonstrates the use of an exit command:

package com.att;

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

public class MIDletCommands extends MIDlet implements CommandListener {

    private Command commandExit;

    private Display display;

    public MIDletCommands() {

        display = Display.getDisplay( this);

        commandExit = new Command("Exit", Command.EXIT, 1);

    }

    //Create text box and add the command.

    public void startApp() {

        TextBox tb = new TextBox("MIDletCommands", "MIDletCommands ", 256, 0 );

        tb.addCommand( commandExit );

        tb.setCommandListener( this );

        display.setCurrent( tb );

    }

    public void pauseApp() {}

    public void destroyApp( boolean unconditional ) {}

    //This is where the app should respond to commands.

    public void commandAction( Command command, Displayable disp ) {

        if ( command == commandExit ) {

            destroyApp( false );

            notifyDestroyed();

        }

    }

}

Updated: 09/02/2011 | Created: 09/03/2010
(open topic page)

JSR 179, or the Location API, gives developers the means to harness one of the most important and powerful capabilities in a mobile device¿it always knows where it is. This API, contained in the javax.microedition.location package, retrieves a device's location in a consistent, standardized fashion using the geospatial coordinates of latitude, longitude, and altitude. Latitude values range from 0 - 90 degrees north or south of the equator; longitude values range from 0 - 180 degrees east or west of the Prime Meridian, marked at Greenwich, England (UK).

Note: To protect the privacy and security of our mobile subscribers, AT&T opens access to the Location API only to developers who have established a trusted business relationship with AT&T. If you are interested in using the Location API and would like to become a trusted AT&T partner, begin the certification process.

How to use JSR 179

To use JSR 179, you must first create a Criteria object. The Criteria object can contain such characteristics as latency, speed, need for altitude, and accuracy. Here's some code that demonstrates creating a Criteria object:

// Sets horizontal accuracy to 20m.
Criteria criteria = new Criteria();
criteria.setHorizontalAccuracy( 20 ); 

After you build your Criteria object, you must create a location provider using that object:

LocationProvider locationProvider = LocationProvider.getInstance( criteria ); 

And finally, here's how to get the actual location of the mobile device:

// Sets a 2 minute timeout
Location location = locationProvider.getLocation( 120 );
Coordinates coordinates = location.getQualifiedCoordinates();
if( coordinates != null ) {
  // Get latitude & longitude
  double latitude = coordinates.getLatitude();
  double longitude = coordinates.getLongitude();
} 
Updated: 09/02/2011 | Created: 01/18/2011
(open topic page) Here is basic code for the simplest of MIDlets—"Hello, World!" This MIDlet prints the text to the screen using a MIDlet class and a Canvas class. Take note of the three required methods which are part of the MIDlet class: startApp(), pauseApp(), and destroyApp().
package com.att;
 
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class HelloWorldMIDlet extends MIDlet {
    //kv Constructor
    public HelloWorldMIDlet() {}

    public void startApp() {
      Canvas canvas = new HelloWorldCanvas();
      Display display = Display.getDisplay( this );
      display.setCurrent( canvas);
   }

   public void pauseApp() {}

   public void destroyApp( boolean unconditional ) {}
}

class HelloWorldCanvas extends Canvas {
   public void paint( Graphics g ) {
      g.setColor( 255, 255, 255 );
      g.drawString("Hello World!", 0, 0, g.TOP | g.LEFT);
   }
} 

Updated: 09/02/2011 | Created: 01/21/2011
(open topic page)

JSR 179, or the Location API, can be a bit tricky to master because of device-specific differences in not only the hardware implementations of the GPS functionality, but also in the software implementations. On the software side, much of the confusion lies around setting up your Criteria object properly because some devices allow you to set certain criteria while others don't. This inconsistency can be a puzzle; in some cases it may be impossible to write code that will work on all devices.

To alleviate some of the challenge with JSR 179, make sure first and foremost that your app is signed with an AT&T Trusted certificate. This will prevent any security exceptions. (If you are interested in using location APIs and would like to become an AT&T trusted partner, learn about and begin the certification process.)

Secondly, if your LocationProvider.getInstance() method is returning null, your target device may not support some of the criteria that you're attempting to set. In order to debug this, we recommend starting with the most basic setup; that is, instantiating your LocationProvider with a default Criteria object like so:

Criteria criteria = new Criteria();
LocationProvider locationProvider = LocationProvider.getInstance( criteria );

After you've verified that this most basic setup works, you can go about fine-tuning your Criteria object and experimenting with which criteria settings work and which don't. Here's an example of setting the criteria for assisted and autonomous GPS modes:

// Assisted GPS mode
cr.setHorizontalAccuracy( 500 );
cr.setVerticalAccuracy( 500 );
cr.setPreferredPowerConsumption( Criteria.NO_REQUIREMENT );

// Autonomous GPS mode
//cr.setHorizontalAccuracy( Criteria.NO_REQUIREMENT );
//cr.setVerticalAccuracy( Criteria.NO_REQUIREMENT );
//cr.setCostAllowed( false );
//cr.setPreferredPowerConsumption( Criteria.POWER_USAGE_MEDIUM );

Be very wary with the setHorizontal() and setVertical() methods, as some devices will return a null LocationProvider if the horizontal or vertical criteria are set to less than a certain threshold. For example, the Samsung Rugby II (SGH-A847) returns a null LocationProvider if the horizontal or vertical criteria is set to less than 100 meters. The Rugby II will also return a null LocationProvider if setCostAllowed() is set to false.

Along these same lines, some devices like the Rugby II may not support getHorizontalAccuracy() and getVerticalAccuracy(). They will simply return null for these methods even if the Criteria object is set up with the default values for horizontal and vertical accuracy.

Finally, it's important to keep in mind that acquiring location in mobile apps is still a work in progress. Because location is not yet an exact science, don't expect to be able to get exact measurements. Measurements within 10 meters are well within the accuracy thresholds for GPS. It's also prudent to expect that your measurements may jump around a bit; you can smooth out your measurements by taking averages over time and throwing out the outliers.

Updated: 09/02/2011 | Created: 02/22/2011
Resources
(open topic page)

J2ME applications connecting through the WAP gateway may be tested against the AT&T developer gateway from the BlackBerry JDE.

WAP applications connecting through the WAP gateway must be tested using a production-quality device against the production wireless network.

Configuring the BlackBerry Simulator for the AT&T Test Gateway 

If you are testing applications that require an HTTP connection, you must first start the Mobile Data Service simulator:

  1. From the BlackBerry JDE, select the EDIT menu, and then click PREFERENCES.
  2. Select the SIMULATOR tab.
  3. Select the "Launch Mobile Data Service (MDS) with Simulator" checkbox.

Command line options are then set to configure the simulator to work with a test gateway:

  1. Select the EDIT menu, and then click PREFERENCES.
  2. Select the SIMULATOR tab.

In the Simulator Command line field, add options after the OsLoader.exe OsHh3G.d11 entry.
The following command line options enable the simulator to connect to test gateways:

  • The /RegAddress option turns the registration server on with the following entry:
    (IP_ADDRESS:DEST_PORT;SRC_PORT/APN) or off (none); none is the default.
  • The /RPORT option sets the socket port and APN of the handheld.
  • The /RSMS option sets the SMS server to IP address on ports send and receive. This enables you to simulate receiving SMS messages.

 

Updated: 09/02/2011 | Created: 05/26/2010
(open topic page)

The architecture of the Java programming language holds the promise of applications that you can "write once, run anywhere." In reality, however, Java ME (the version of Java scaled down for wireless devices) comes installed in a diverse array of devices. From custom OEM extensions to variances in screen size, most J2ME developers often have to "write once, run once" (or at least on only one device). Although you may not be able to completely re-use your code, there are few architectural decisions about relative positioning versus absolute positioning that you can make up front to simplify porting your applications to other devices later.

Devices have different application size limitations. Decide with your team up front which features you would remove if you had to make your application much smaller. Clearly segregate and comment your code so that these features can be easily identified and removed later.

Use relative positioning when you draw objects rather than absolute positioning.

Where possible, use one component of your MIDlet suite to hold the specific properties for each device, so that your logic and presentation can be managed separately.

It may even be possible to create a dynamic JAD file that grabs the UA Profile from the HTTP header and writes a custom attribute for the screen size for that device. You can store these values in the RMS and access them programmatically from within the MIDlet suite.

Always keep in mind that you may want to port your wireless application later, even if you don't think so now. Planning for this up front can save you time later!

Updated: 09/02/2011 | Created: 05/26/2010