What's new? | Help | Directory | Sign in
Google
             
Search
for
Updated Jun 23, 2008 by Sam.Halliday
Labels: Phase-Implementation, Featured
DevelopersGuide  
for developers wishing to use OpenLAPI

Please remember that OpenLAPI uses the LGPL Open Source License. MIDlets that are distributed with OpenLAPI included do not need to be open sourced, but any changes to OpenLAPI must be. Use of the JSR-179 API does not require you to open source your software.

Please use Google Code to report bugs and feature requests. We would also really like to hear from people using OpenLAPI to include on a list that may appear here at some point.

Installation

There are 2 jarred library files in the distribution. The openlapi-*.jar file contains the com.openlapi.* API which is the core of OpenLAPI. The openlapi-jsr179-*.jar contains the javax.microedition.location.* API (JSR-179) which wrap the OpenLAPI backend.

If you wish to do development for a device which does not have the JSR-179 standard, include the openlapi.jar file with your MIDlet and use the com.openlapi.* API. If you wish to do development for a device which has the JSR-179 standard, include both jar files in your development classpath, but do not include either with your MIDlet.

You may want to link the jar to the source within your IDE for easy access to the documentation. The jar is approximately 67K and includes kXML2. An obfuscation program such as Proguard will reduce the total to ~10K.

Unfortunately it is not possible for OpenLAPI to use JSR-179 at runtime if it is detected. This is not a problem with OpenLAPI but of the handset manufacturers and the Java Unified Testing Initiative. For more details please read this blog post. The short version is that many manufacturers require a MIDlet to be signed. But in order to get your MIDlet signed, you must only target devices which have JSR-179... meaning that you would end up having to build 2 different distributions of your MIDlet anyway. The inclusion of a smarter OpenLAPI would prevent you from getting your MIDlet signed for non-JSR-179 compliant devices. We may release a version of OpenLAPI soon which allows you the choice, but unfortunately it wouldn't achieve much.

Use

OpenLAPI supports several back-ends, but will use a GPS device over Bluetooth as default. You may specify the mode by creating a resource file named /OpenLAPI-mode.txt in your MIDlet containing a single line of text which may be one of

We would love to use the `MIDlet.getResource` method call for this, but unfortunately it isn't static so we can't reference it from within OpenLAPI.

Future releases will offer more options for each mode.

GPS --- Global Positioning System over Bluetooth

The GPS mode will only work if you have a bluetooth library JSR-82 (such as Avetana or Bluecove) on your development machine and have a bluetooth GPS device. JSR-82 is also required on the device.

OpenLAPI will look for any bluetooth devices in the area and connect to the first that contains the String "GPS" in their name. If you register a LocationListener, OpenLAPI will continuously poll the GPS device. However, if your use is calling getLocation(), it will start up a new connection each time. It is very robust against dropped connections.

NMEA --- log file record of a GPS device

As of version 0.9.9, OpenLAPI ships with an NMEA logger as a standalone MIDlet in the folder tests/com/openlapi/NMEALogger.java. You may edit this to point to an HTTP server which the log file will be POSTed to. If you then include the resultant file as a resource called nmea.log, it can be used to emulate a GPS device. It will be played back at a rate of one sentence per second.

KML --- Google Earth

The default behaviour is to parse the resource named "OpenLAPI.kml" and search for Placemark objects, which include descriptions and longitude/latitude pairs.

The emulator will cycle through these objects in order, and then reverses to the beginning, in a loop. This allows the creation of trails which may be played out. The KML mode will not fail unless there is a problem with the file (so is therefore not good for testing faulty devices). If the file does not exist, OpenLAPI will use the shipped file (which is also a good starting point as a template for creating user-defined trails).

LMS --- LandmarkStore

The location API has an interface for creating a persistent store of Landmark objects. The LMS backend will pick a random entry each time the Location is requested. This mode was intentionally designed to allow the developers to change the store on-the-fly, so as to emulate situations where the device is temporarily not able to obtain the Location. This mode is best for testing how well your timeout code works! Remember Graceful degradation.

Quick Tutorial

The entry point to obtain a Location object is always the LocationProvider class. Request a LocationProvider by calling

        Criteria criteria = null; // read the docs on setting a criteria
        LocationProvider provider = null;
        try {
            provider = LocationProvider.getInstance(criteria);
        } catch (LocationException e) {
                 // oh no!
        }

Once you have the provider you can request a Location anytime by calling (don't forget to test for validity).

        Location location = null;
        try {
            // 20 second timeout
            location = provider.getLocation(20);
        } catch (Exception e) {
            // oh no! could be one of 4 Exceptions so be more thorough than this
        }
        // don't forget to test that the Location is valid
        if (!location.isValid()){
            // oh no!
        }

It is possible to poll the device for periodic updates by implementing the LocationListener interface and attaching this to the LocationProvider. This polling "server" will then run in another thread, returning Location objects as agreed, which may be invalid. The first valid Location object will be returned at any time, as soon as it becomes available (i.e. not necessarily at the defined interval).

    LocationListener ll = new MyLocationListener();
    // -1 are defaults
    provider.setLocationListener(ll, -1, -1, -1);
    .
    .
    .
    // remove the listener when finished
    provider.setLocationListener(null, -1, -1, -1); 

You may also obtain an alert when the Location comes within a certain radius of a specified Coordinates. Simply implement the ProximityListener interface and attach an instance to the LocationProvider. Note that this does not guarantee that the ProximityListener will be called as soon as the device is in range as it does not periodically poll the LocationProvider, and devices may be unreliable. It is wise to use ProximityListener in conjunction with LocationListener. Note that the computational cost of calculating the distance between two Coordinates objects is very expensive, but this implementation has some neat hacks that reduce the overhead for proximity checking.

    // the coordinates of a small village in Scotland, unknown altitude
    Coordinates cramond = new Coordinates(55.973894, -3.305984, Float.NaN);
    int radius = 10055;
    ProximityListener pl = new MyProximityListener();
    try {
        LocationProvider.addProximityListener(pl, cramond, radius);
    } catch (Exception e) {
        // oh no!
    }

Notes

The specification states that the system variable microedition.location.version be set to 1.0 and that there be a security policy regarding the access to sensitive classes. Because J2ME apps cannot set system variables, it is the developer's responsibility to set this system property in the emulator environment.

On the security policy, OpenLAPI allows you full access to the entire API, so read the documentation carefully when setting security permissions in your jad/manifest file. The functionality to enable a security policy is there, but this may be emulator dependent.

The creation of Criteria objects is complete and will help your code to function more correctly on embedded devices. However, they are completely ignored by the OpenLAPI LocationProviders. This is for the very good reason that you explicitly choose the back-end (without disrupting your JSR-179 compliant code), so you should know exactly how accurate your choice is.


Sign in to add a comment